Debugging GitHub Actions "Pending-Forever" Silent Failures
These articles are AI-generated summaries. Please check the original sources for full details.
When GitHub Actions Goes Silent: The Pending-Forever Bug I Hit Shipping My MCP Server to npm
GitHub Actions workflows for the safari-mcp server stalled indefinitely with zero jobs scheduled despite showing a “queued” status. The system provided no UI error banners, leaving releases stuck for over 125 hours. This occurred despite using standard runner labels and no deployment environments.
Why This Matters
Technical reality often diverges from UI reporting; GitHub Actions does not surface billing exhaustion errors within the run detail page, leading to “silent” failures that appear as permanent pending states. This is exacerbated by a 10x billing multiplier for macOS runners, which can deplete a standard 2,000-minute free tier in just 20 builds, potentially blocking entire CI/CD pipelines due to serialized concurrency groups.
Key Insights
- macOS runners on GitHub Actions are charged at a 10x multiplier compared to Linux runners as of 2026.
- Billing exhaustion for specific runner types results in a “pending” status with empty jobs and pending_deployments arrays in the GH API.
- Concurrency groups can serialize and block new runs on available runners (like Ubuntu) if previous runs on exhausted runners (like macOS) remain in the queue.
- The mcp-publisher tool supports non-interactive authentication using the
gh auth tokenvia the-tokenflag for headless environments. - Workflow dispatch with tag inputs allows re-triggering specific releases without deleting and recreating GitHub Release objects.
Working Examples
Adding a manual trigger with tag input to recover stuck automated releases.
on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "Tag to publish (e.g. v2.9.3)"
required: true
type: string
Portable shell script to download architecture-specific binaries across macOS and Linux.
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
if [ "$ARCH" = "x86_64" ]; then ARCH=amd64; fi
if [ "$ARCH" = "aarch64" ]; then ARCH=arm64; fi
curl -sL "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_${OS}_${ARCH}.tar.gz" -o mcp-publisher.tar.gz
Non-interactive authentication for the MCP Registry CLI using the GitHub CLI token.
GH_TOKEN=$(gh auth token)
mcp-publisher login github -token "$GH_TOKEN"
mcp-publisher publish
Practical Applications
- Implementing workflow_dispatch with fallback logic using
${{ github.event.inputs.tag || github.ref_name }}to enable manual recovery of failed automated releases. - Avoiding hardcoded OS-specific binaries like ‘darwin’ in CI scripts to allow immediate switching to Linux runners during macOS billing depletion.
- Using the GitHub CLI (gh) token as a PAT for automated publishing tools to bypass interactive browser-based logins in headless CI or local emergency environments.
References:
Continue reading
Next article
Optimizing High-Throughput Workloads with InfluxDB Time-Series Database
Related Content
Dynamic Parameter Handling in GitHub Actions via JSON Templating
GitHub Actions now supports dynamic parameter passing through JSON templating, enabling flexible config management.
Securing CI/CD: A Multi-Layered Toolkit for GitHub Actions Integrity
Developer Olivier Buitelaar shipped five open-source tools in one day to solve the critical issue of silent GitHub Actions workflow failures.
Automate Repository Maintenance with New Stale Branch Cleaner and Changelog Actions
Olivier Buitelaar released two new GitHub Actions to automate repository hygiene and changelog generation using 90-day inactivity thresholds and conventional commits.