Diagnosing Reusable Workflow Invocation Failures in GitHub Actions
A step‑by‑step diagnostic guide for the most common reasons a GitHub Actions caller workflow cannot invoke a reusable workflow, with a symptom‑to‑cause table, ordered verification commands, and concrete YAML examples.
28 May 2026, 04:02 UTC

Problem
A caller workflow that uses uses: owner/repo/.github/workflows/reusable.yml@ref fails with messages such as Unable to resolve reusable workflow reference, Required input "X" not provided, or Permission denied. The failure appears in the Actions log before any job runs, making it hard to know whether the issue is a typo, a missing trigger, or a permission problem.
Quick‑reference diagnostic table
| Observed symptom | Most likely cause |
|---|---|
Unable to resolve reusable workflow reference (404) | Wrong file path, branch, or tag in the uses value |
Workflow "..." does not have a "workflow_call" trigger | Target workflow missing on: workflow_call |
Required input "foo" not provided | Caller's with: block omits a mandatory input defined in the reusable workflow |
Permission denied or Resource not accessible by integration | Caller lacks contents: read (or broader) permission for the target repo, or token scope insufficient |
Secret "MY_SECRET" not found | Secret not defined in caller repo, not passed in secrets:, or caller missing secrets: inherit / explicit list |
| Fork or private‑repo caller cannot reach internal reusable workflow | Repository/organization settings block cross‑repo workflow calls |
Ordered checks & fixes
-
Verify the
usespath and refOpen the caller workflow file and locate the
uses:line. The format isowner/repo/.github/workflows/file.yml@ref. Confirm:- The file exists in the target repository at the exact path.
- The
ref(branch, tag, or SHA) is spelled correctly and still exists.
Check via GitHub CLI (run locally, requires
reposcope token):gh api repos/OWNER/REPO/contents/.github/workflows/reusable.yml?ref=main --jq '.name' # Expected output: reusable.ymlIf the command returns a 404, correct the path or ref in the caller.
-
Confirm the reusable workflow declares
on: workflow_callOpen the target workflow file. It must contain at the top level:
on: workflow_call: inputs: environment: required: true type: string secrets: DEPLOY_TOKEN: required: trueIf the
workflow_callblock is missing, add it. Without it the workflow cannot be invoked as reusable. -
Match required inputs
List every
inputs:entry markedrequired: truein the reusable workflow. In the caller, each must appear underwith:with the exact same key name (case‑sensitive). Example caller snippet:jobs: call-reusable: uses: myorg/infra/.github/workflows/deploy.yml@main with: environment: production # matches required input secrets: DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}Missing or misspelled keys cause the “Required input not provided” error.
-
Validate caller permissions
At minimum the caller needs
contents: readon the target repository. Add apermissions:block to the caller workflow (or to the specific job):permissions: contents: readIf the reusable workflow lives in a different organization, ensure the caller’s token (the default
GITHUB_TOKENor a PAT) hasreposcope for that org. For self‑hosted runners, verify network egress toapi.github.comand the target repo. -
Pass secrets and environment variables correctly
Reusable workflows only receive secrets explicitly listed in the caller’s
secrets:block (or viasecrets: inheriton GitHub Enterprise Cloud). Example:secrets: DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }} # or secrets: inheritCheck that each secret name matches the
secrets:declaration in the reusable workflow. Missing secrets surface as “Secret "NAME" not found”. -
Check repository/organization cross‑repo policies
In the target repo’s Settings → Actions → General, confirm “Allow reusable workflows” is enabled for the appropriate scope (private, internal, public). For forks, the fork must have “Run workflows from fork pull requests” enabled and the caller must use a token with
reposcope (e.g., a PAT stored as a secret).
Escalation criteria
- All six checks pass but the caller still fails with a generic
Internal errororUnexpected error. - The reusable workflow resides in a repository that is archived, deleted, or has been transferred.
- Self‑hosted runner logs show TLS/connection errors to
github.com. - Organization policies (e.g., SAML/SSO enforcement) block the
GITHUB_TOKENfrom accessing the target repo.
When any of the above apply, open a GitHub Support ticket with the workflow run URL, the exact uses string, and the runner type (GitHub‑hosted vs self‑hosted).
Verification after fix
Create a temporary branch, push the corrected caller workflow, and trigger a run (via workflow_dispatch or a PR). In the run log, the “Set up job” step should show Resolving reusable workflow … followed by a green check. The job should then proceed to the reusable workflow’s first step.
Limitations
This guide covers the most common static‑configuration failures. Dynamic failures (e.g., a reusable workflow that later calls an action that fails) are outside scope. Also, GitHub may introduce new workflow_call features (e.g., output mapping) that add additional validation rules; always cross‑check with the official documentation for the version of GitHub Actions you use.
Diagram
- Caller Workflow
- Reusable Workflow
- GitHub API (resolution)
- Runner (execution)
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.