GitHub Actions Unable to resolve action, and which half failed
GitHub Actions Unable to resolve action appears in two forms, and the difference between them is the whole diagnosis: one says the repository could not be found, and the other says the repository was found but the ref you asked for was not. Nothing downloads and no action code runs in either case, because the reference is resolved before anything is fetched.

What this error means
A step fails at the very start with a single line and no other output. There is no setup log for the action, no inputs echoed, nothing from the action itself, because the action was never obtained. The step that fails is often one nobody touched, in a workflow that has been green for months, which makes a repository rename or a deleted tag the first thing to suspect rather than the workflow file.
Error: Unable to resolve action `gigalixir/gigalixir-action@v1`, unable to find version `v1`Read the ending of the line, not the beginning
Both forms open the same way, so the informative part is what comes after the reference. An ending of "repository not found" means the owner and repository part of your uses value did not resolve to something the run is allowed to see. An ending of "unable to find version" means it did resolve, and the tag, branch or commit after the @ did not exist there.
That split maps to two different searches. For the first, whose reported form is Error: Unable to resolve action. Repository not found: ytanikin/PRConventionalCommits, check the spelling and case of the path, check whether the repository was renamed or made private, and check whether this run has access to it at all. For the second, the repository is fine and you are looking at a tag question: a major version tag that was never published, a tag that was deleted or moved, or a branch that was renamed.
Resolution happens before any download, which is why neither form leaves a partial log. The runner collects the references a job needs and asks the service to resolve them, and a failure there means the job stops with one line rather than with a half-downloaded action.
| How the line ends | How far the lookup got | What to check first |
|---|---|---|
repository not found | the owner and repository never resolved | spelling, a rename, a private repository, org policy |
unable to find version x`` | the repository resolved, the ref did not | whether the tag or branch exists on that repository |
| names a repository you renamed | the redirect was not followed | update the uses path to the current name |
| names your own private action | the run has no access to it | repository settings for Actions access |
Common causes
The tag or branch in the reference does not exist
Usually a major version tag the maintainer has not published, or a tag that was deleted or renamed during a release. The message names the version, which is the fastest confirmation available, and listing the repository's tags settles it in one command.
The repository was renamed or moved
A uses reference to the old owner or name can stop resolving even though the browser redirect still works, so a workflow that nobody edited fails on a step that used to pass. This is the version that produces the most confusing bug reports.
The action is private and not shared with the calling repository
A private action has to allow access from other repositories in the organization. Without that, resolution fails with the repository not found ending, which sends people to check a path that was never wrong.
The path is misspelled or wrongly cased
Less common than the others and worth ruling out first because it costs nothing. In our experience the case version appears when a reference is retyped from a README rendered with different capitalization.
How to fix it
List the refs on the action repository
Ask the repository what it actually publishes before changing anything. If the tag you referenced is not in the list, the reference is the problem; if it is, you are looking at an access or naming question instead.
gh api repos/OWNER/ACTION/git/matching-refs/tags --jq '.[].ref' | tail -20Pin to a commit SHA for anything that matters
A commit SHA cannot be moved or deleted by the action's maintainer, which removes this whole failure mode for that step. The documentation recommends it as the safest reference for stability and security, and a dependency updater can still raise pull requests to advance it.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1Allow a private action to be used by other repositories
- Open the settings of the repository that holds the action, not the one running the workflow.
- In the Access section, select the option making it accessible from repositories in the organization.
- Re-run the failing job and confirm the ending of the message changes or disappears.
- If the action is only ever used by one repository, consider moving it into that repository instead.
Reference a local action by path when it is internal
Checking the action out and calling it with a relative path avoids the action lookup entirely, because the reference resolves against the workspace. This is the right shape for an action that has no reason to be discoverable outside the repository.
- uses: actions/checkout@v7
- uses: ./.github/actions/buildWhy a major version tag can vanish
The convention that uses: owner/action@v3 keeps working is a convention, not a guarantee. It relies on the action's maintainer publishing and moving a lightweight v3 tag alongside each v3.x.y release, and the documentation says as much: it notes that the behavior of major version tags is at the discretion of the action's author.
So a README instructing you to use @v3 can be ahead of the tags, behind them, or simply wrong, and the failure you get names the version rather than the README. Two public reports quoted in this hub are exactly that: a README saying @v1 for an action whose v1 tag had not been published, and another saying @v3 for the same reason.
The response is not to avoid major tags, which are genuinely useful, but to verify the ref exists when you first add it and to know that a pin to a commit SHA is the only reference that cannot be moved out from under you. The documentation recommends the SHA for stability and security for that reason.
gh api repos/OWNER/ACTION/git/matching-refs/tags/v --jq '.[].ref'Private actions, and the access that is not the token
When the action lives in a private repository in your own organization, the failing form is usually repository not found, which reads as though the path is wrong. The path is fine. What is missing is that the repository holding the action has not allowed its workflows and actions to be used by other repositories in the organization, which is a setting on the action's repository rather than on the workflow's.
This one is worth stating plainly because the instinct is to reach for a token. A personal access token with repository access does not change the answer, because the resolution is not a clone you are authenticating: it is the service deciding whether this run may use that action. The fix is a setting.
The alternative, which avoids the question entirely, is to check the action out into the workspace and call it by a relative path. A local uses: ./path reference resolves against the checked out repository rather than through the action lookup, and it is the pattern to reach for when an action is genuinely internal.
Why there is no recorded run on this page
Both forms of the message are produced when the run resolves its action references, which happens before the action is downloaded and therefore before there is anything for a runner to log beyond the one line. A Latchkey recording would consist of that line and nothing else.
More to the point, producing one means writing a workflow that references a repository or a tag that does not exist, which is manufacturing the evidence rather than observing it. Both forms are quoted here from public reports where real repositories and real missing tags produced them, which is a stronger provenance than a failure we would have staged.
How to prevent it
- Verify that a referenced tag exists at the moment you add the reference.
- Pin actions you depend on to commit SHAs and let an updater advance them.
- Update
usespaths in the same change that renames a repository. - Set access on the action's repository when you first publish an internal action.
Frequently asked questions
What is the difference between repository not found and unable to find version?
uses value never resolved, so spelling, renames, privacy and policy are in scope. Unable to find version means the repository resolved and the tag, branch or commit after the @ does not exist there.