Skip to content
LatchkeyLatchkey home

Git LFS "files that should have been pointers, but weren't" in CI

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

  1. Confirm the pattern in .gitattributes matches the listed files.
  2. Rewrite the matching files into pointers with git lfs migrate import.
  3. Force-push the rewritten history and re-run CI.
Terminal
git lfs migrate import --include="*.psd,*.parquet" --everything
git push --force-with-lease

Fix a single working copy without a rewrite

For files not yet pushed, touch and recommit them so the clean filter converts them to pointers.

Terminal
git rm --cached assets/logo.psd
git add assets/logo.psd
git commit -m "Store logo.psd via LFS"

Using this in CI

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@v4
  with:
    fetch-depth: 0   # history, tags, and git describe all need this

- run: |
    git rev-parse --is-shallow-repository   # expect false
    git 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.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card