[BUG] Self-hosted runner: resuming a session fails to start when an add_repo'd repo uses Git LFS — smudge has no credentials for the session git proxy

Status Open
Reported on v2.1.247
Maintainer reply None cached
Activity 0 comments · opened Aug 27, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

On a self-hosted runner environment (environment_kind: byoc), resuming a session onto a fresh pod re-clones the session's repos — including repos attached mid-session via add_repo, which are not part of the session's initial source set. If such a repo uses Git LFS, the LFS smudge cannot obtain credentials for the session git proxy, and the session dies before it starts:

The session process failed to start.

The pack fetch itself succeeds — only the LFS smudge fails. git-lfs runs the smudge as its own process and resolves credentials through git credential, rather than inheriting whatever the fetch used. At that point in resume-time startup the credential helper the harness installs at /workspace/.runner/git-proxy-cred is not usable yet, so git-lfs gets nothing back, git falls through to prompting, prompts are disabled, and the smudge fails.

Because the harness's own ~/.gitconfig sets filter.lfs.required = true, a failed smudge is fatal rather than degrading to a pointer file — so the checkout aborts and startup never completes.

This is specific to the resume path. Mid-session, LFS works correctly: cloning the same repo through the same session git proxy resolved all 7 LFS objects and negotiated auth=basic, and the batch API answers 401 unauthenticated / 200 with the session token. So the proxy's LFS support is fine — this is a credential-availability bug in resume-time cloning that surfaces only on LFS repos, because they are the only ones needing a second, independently-authenticated request.

Two sessions hit this, one week apart, on the same pool. In both cases the workaround was to abandon the runner and teleport the session to a local executor.

What Should Happen?

Resume-time clones of add_repo'd repos should have working git credentials in place before checkout runs, so the LFS smudge can authenticate to the session git proxy. A session should not fail to start because an attached repo happens to use Git LFS.

Error Messages/Logs

The session process failed to start. You can try again by sending a new message or starting a new session.

Last output before exit:
git reset failed: fatal: could not read Username for 'https://api.anthropic.com': terminal prompts disabled
fatal: could not read Username for 'https://api.anthropic.com': terminal prompts disabled
error: external filter 'git-lfs filter-process' failed
fatal: path/to/data.jsonl: smudge filter lfs failed
fatal: could not read Username for 'https://api.anthropic.com': terminal prompts disabled
Downloading path/to/data.jsonl (74 KB)
fatal: could not read Username for 'https://api.anthropic.com': terminal prompts disabled
Error downloading object: path/to/data.jsonl (<oid>): Smudge error: Error downloading path/to/data.jsonl (<oid>): batch response: Git credentials for https://api.anthropic.com/v1/session_ingress/session/<session-id>/git_proxy/<org>/<repo>.git not found.
Errors logged to '/workspace/<org>/<repo>/.git/lfs/logs/20260827T152752.636004798.log'.
Use `git lfs logs last` to view the log.
error: external filter 'git-lfs filter-process' failed
fatal: path/to/data.jsonl: smudge filter lfs failed

Steps to Reproduce

  1. Start a session in a self-hosted runner environment (here a ClaudeRunnerSet pool, <pool-name>, one pod per session).
  2. Mid-session, attach a repository that Git-LFS-tracks files, using add_repo. In our case <org>/<repo>, which tracks path/to/*.jsonl via a .gitattributes containing *.jsonl filter=lfs diff=lfs merge=lfs -text (7 objects, ~74 KB each).
  3. Let the session go idle until it is released server-side (this pool is configured with releaseIdleSessionMinutes: 10), so the next message resumes onto a fresh pod.
  4. Resume the session by sending a message.
  5. The resume-time clone of the attached repo fails in the LFS smudge, and the session process never starts.

Note that a repo without LFS resumes fine, and the same LFS repo clones fine when done by hand during a live session — so the reproduction depends on the repo being both LFS-backed and attached via add_repo.

Diagnostic detail

Relevant config observed inside a session pod:

  • /home/claude/.gitconfig (harness-written, mtime ~3 min after pod start) contains both the credential helper and the LFS filter block:

``
[credential "https://api.anthropic.com"]
helper = !'/workspace/.runner/git-proxy-cred'
useHttpPath = false
username = unused
[filter "lfs"]
required = true
``

  • /workspace/.runner/git-proxy-cred is a shell script that emits $CLAUDE_CODE_SESSION_ACCESS_TOKEN. Both it and ~/.gitconfig are recreated per pod, which is why ordering against the resume-time clone matters.
  • Because ~/.gitconfig re-declares filter.lfs.required = true, it overrides the runner image's /etc/gitconfig, so the escalation-to-fatal cannot be softened from the image side.

Workaround, for anyone else hitting this: set GIT_LFS_SKIP_SMUDGE=1 in the pod environment. Checkout then writes pointer files, which needs neither network nor credentials, so the session starts; git lfs pull afterwards materialises the real content (verified to work with the variable still set). It has to be pod env — the failing checkout runs during harness startup, before any session wrapper exists.

Related, filed separately as anthropics/claude-code#90165: in a self-hosted session there is no insteadOf rewrite for https://github.com/..., so the clone command add_repo instructs you to run fails with fatal: could not read Username for 'https://github.com': No such device or address; the /v1/session_ingress/.../git_proxy/... URL must be substituted by hand.

Claude Model

Opus

Is this a regression?

I don't know

Claude Code Version

A custom self-hosted runner image (Ubuntu 26.04 arm64, git 2.53.0, git-lfs 3.7.1) tracking Anthropic's apt latest channel. 2.1.247 (Claude Code) on the local executor the session was teleported to.

Platform

Anthropic API

Operating System

Other Linux

[!NOTE] Repository, path, and pool names in this report are redacted placeholders (<org>/<repo>, path/to/...); the specifics are not relevant to the mechanism and can be shared privately if they would help triage.

---

Investigated and drafted by Claude Code; filed by the repository owner.

View original on GitHub ↗