Limitations of the REST API Fallback in actions/checkout
The REST API fallback in actions/checkout disables Git-LFS, submodules, SSH authentication, sparse checkout, and shallow fetch capabilities because it downloads a static repository archive instead of performing a proper Git clone.
When the actions/checkout action runs in a GitHub Actions workflow, it normally relies on the Git command-line client to clone your repository. However, if a suitable Git binary is unavailable on the runner, the action falls back to downloading the repository archive via the GitHub REST API. This fallback path, implemented in src/git-source-provider.ts, imposes strict limitations that can break workflows relying on advanced Git features.
How the Fallback Mechanism Works
The action attempts to create a Git command manager through gitCommandManager.createCommandManager at the start of execution. If this initialization throws an error—indicating Git is not installed or not functional—the code path switches to the REST API fallback. According to the source code in src/git-source-provider.ts (lines 78-90), this switch only occurs when Git is unavailable and lfs: true is not set in your workflow configuration.
When triggered, the action calls downloadRepository from src/github-api-helper.ts to fetch a compressed archive of the repository at the requested ref. Because this returns a static snapshot rather than a functional Git repository, several Git-specific operations become impossible.
Critical Limitations When Using the REST API Fallback
Git-LFS Objects Cannot Be Fetched
Git-LFS (Large File Storage) is completely unsupported in REST API fallback mode. If your workflow sets lfs: true and the Git command manager cannot be created, the action throws an error immediately (lines 83-92 in src/git-source-provider.ts). This occurs because LFS objects are stored outside the main repository archive and require Git's LFS extension to fetch them separately.
Submodule Cloning Is Disabled
Submodules are not included in the REST API archive and cannot be initialized without Git. The action explicitly throws an error when submodules: true is configured but the fallback path is taken. Each submodule requires its own Git clone operation, which is impossible when downloading a single static archive.
SSH Authentication Is Not Supported
The REST API download endpoint only accepts HTTP(S) authentication tokens. If your workflow provides an ssh-key input while running in fallback mode, the action fails with an authentication error. SSH keys are irrelevant to the archive download endpoint, which requires a valid authToken (personal access token or GITHUB_TOKEN) passed through HTTP headers.
Sparse Checkout and Cone Mode Are Unavailable
Sparse checkout functionality—configured via the sparse-checkout input—is effectively ignored during REST API fallback. The sparse-checkout logic is only applied when a Git command manager exists, as it requires Git to selectively populate the working directory. The archive endpoint always provides the complete repository tree, making selective file retrieval impossible.
Shallow Fetch and Fetch Depth Are Ignored
The fetch-depth parameter has no effect when using the REST API fallback. While Git clones can perform shallow fetches to limit history depth, the archive endpoint provided by GitHub always returns a complete snapshot of the repository at the requested ref. You cannot perform a shallow clone via the REST API.
Tag Movement Cannot Be Detected
Without Git client capabilities, the action cannot verify that a tag still points to the same commit it referenced when the workflow started. In normal operation, Git can re-fetch tags to ensure they haven't moved. The REST API fallback downloads the archive once and cannot detect if the tag was updated to point to a different commit during the workflow execution.
Implementation Details
The fallback logic and its constraints are enforced across three key files:
| File | Role |
|---|---|
src/git-source-provider.ts |
Decides whether to use Git or fall back to the REST API and enforces input validation |
src/github-api-helper.ts |
Contains the downloadRepository helper that performs the archive download via the REST API |
src/git-command-manager.ts |
Creates the Git command manager; its failure triggers the fallback logic |
In src/git-source-provider.ts, lines 78-90 handle the decision to fall back, while lines 83-92 contain the validation logic that throws errors for incompatible inputs like submodules, ssh-key, or lfs: true when Git is unavailable.
Configuration Examples
Standard Git Checkout (Full Features Available)
When Git is present on the runner, all features work normally:
steps:
- uses: actions/checkout@v4
with:
lfs: true
submodules: true
fetch-depth: 1
sparse-checkout: 'src/**'
REST API Fallback (Restricted Configuration)
When Git is unavailable, you must disable incompatible features:
steps:
- uses: actions/checkout@v4
with:
lfs: false
submodules: false
ssh-key: '' # Must not be provided
If the runner lacks Git, the above configuration triggers the REST API download path. The action succeeds only when disallowed options are omitted, downloading the full repository archive at the expense of Git-specific functionality.
Summary
- No Git-LFS: Large files stored via LFS cannot be fetched without a Git client.
- No Submodules: Submodule initialization requires Git cloning capabilities unavailable in archive downloads.
- Token-Only Auth: Only HTTP(S) bearer tokens work; SSH keys cause failures.
- Full Tree Only: Sparse checkout patterns are ignored; the complete repository is always downloaded.
- Complete History: The
fetch-depthparameter is ignored; archives contain full snapshots. - Static Refs: Tags cannot be re-verified after download; you get the state at the moment of the API call.
Frequently Asked Questions
When does actions/checkout use the REST API fallback instead of Git?
The REST API fallback activates when gitCommandManager.createCommandManager throws an error, indicating Git is not installed or not functional on the runner, and when lfs: true is not set in the workflow inputs. This logic is implemented in src/git-source-provider.ts.
Why doesn't the REST API fallback support Git-LFS?
Git-LFS objects are stored separately from the main repository content and require the Git LFS extension to fetch them. The REST API archive endpoint only packages the standard Git tree, omitting LFS pointers and objects, making LFS support impossible without a proper Git installation.
Can I use sparse checkout with the REST API fallback in actions/checkout?
No. Sparse checkout requires Git to selectively populate the working directory according to specified patterns. Because the REST API fallback downloads a complete archive of the entire repository tree, sparse checkout logic—which resides in the Git command manager—is never applied.
How do I know if my workflow is using the REST API fallback?
Check your workflow logs for messages indicating the Git command manager failed to initialize or that the action is downloading the repository via the API. If your workflow fails with errors about submodules, ssh-key, or lfs being incompatible with the current environment while running on a minimal container without Git, you are hitting the REST API fallback limitations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →