Git LFS "files that should have been pointers, but weren't" in CI
By Kaveh Alemi·Latchkey
A file that a .gitattributes pattern tracks with LFS was committed as its real bytes instead of a pointer. git lfs detects the mismatch and the pre-push hook or a CI check refuses to proceed.
What this error means
A push or a git lfs status check fails with "Encountered N file(s) that should have been pointers, but weren't" and lists the offending paths.
git-lfs
Encountered 2 file(s) that should have been pointers, but weren't:
assets/logo.psd
data/sample.parquet
error: failed to push some refs to 'https://github.com/acme/app.git'
Common causes
Files were committed before LFS tracking was added
The .gitattributes rule was added after the files were already staged as content, so the real bytes are in history, not pointers.
A commit bypassed the LFS clean filter
Committing with LFS not installed, or with the filter disabled, stores the file content directly even though a track pattern matches it.
How to fix it
Re-import the paths as pointers
Confirm the pattern in .gitattributes matches the listed files.
Rewrite the matching files into pointers with git lfs migrate import.
CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.
.github/workflows/ci.yml
- uses:actions/checkout@v4with:fetch-depth:0 # history, tags, and git describe all need this- run:|git rev-parse --is-shallow-repository # expect falsegit rev-parse --abbrev-ref HEAD # prints HEAD when detached
How to prevent it
Add .gitattributes LFS rules before committing matching files.
Verify git lfs is installed on every machine that commits.
Add a CI git lfs status check to catch raw content early.
Frequently asked questions
What causes Git LFS "files that should have been pointers, but weren't" in CI?
There are 2 common causes: files were committed before lfs tracking was added and a commit bypassed the lfs clean filter. The .gitattributes rule was added after the files were already staged as content, so the real bytes are in history, not pointers.
How do I fix Git LFS "files that should have been pointers, but weren't" in CI?
There are 2 fixes depending on which cause you have: re-import the paths as pointers and fix a single working copy without a rewrite. Work through them in order, since the first is the most common.
What does Git LFS "files that should have been pointers, but weren't" in CI actually mean?
A push or a git lfs status check fails with "Encountered N file(s) that should have been pointers, but weren't" and lists the offending paths.
How do I stop Git LFS "files that should have been pointers, but weren't" in CI happening again?
Add .gitattributes LFS rules before committing matching files. The prevention section lists 3 changes that keep it from recurring.