paperclipai/paperclip · error · Error

Could not read execution-target Git context

Error message

Could not read execution-target Git context

What it means

prepareGitHubExecutionEnvironment probes the execution-target's Git context by running a shell script that emits a payload delimited by NUL markers (PAPERCLIP_GIT_CONTEXT_V1 ... PAPERCLIP_GIT_CONTEXT_END). This error is thrown when the probe exits non-zero or the delimited payload is absent from stdout, meaning the target's Git state (roots, remotes, etc.) could not be discovered.

Source

Thrown at packages/adapter-utils/src/execution-target.ts:1655

    printf 'PAPERCLIP_RUNNER_NETWORK_ROOT\0%s\0' "$parent/$(basename "$file")"
  fi
done
cwd=$(pwd -P)
top=$(git rev-parse --show-toplevel 2>/dev/null) || top=
if [ -n "$top" ] && [ "$(cd "$top" && pwd -P)" = "$cwd" ]; then
  for kind in --git-common-dir --git-dir; do
    root=$(git rev-parse --path-format=absolute "$kind" 2>/dev/null) || continue
    root=$(cd "$root" && pwd -P) || continue
    printf 'PAPERCLIP_GIT_METADATA_ROOT\0%s\0' "$root"
  done
fi
printf '\0PAPERCLIP_GIT_CONTEXT_END\0'
`;
    const result = await adapterExecutionTargetCommandRunner(remote).execute({
      command: "sh", args: ["-c", probe, "paperclip-git-context", input.hostCredentials ? "host" : "managed"],
      cwd: input.cwd, timeoutMs: 15_000,
    });
    if (result.exitCode !== 0) throw new Error("Could not read execution-target Git context");
    const payload = result.stdout.split("\0PAPERCLIP_GIT_CONTEXT_V1\0")[1]?.split("\0PAPERCLIP_GIT_CONTEXT_END\0")[0];
    if (payload === undefined) throw new Error("Could not read execution-target Git context");
    discovered = {};
    const records = payload.split("\0");
    const roots: string[] = [];
    const networkRoots: string[] = [];
    for (let index = 0; index + 1 < records.length; index += 2) {
      const key = records[index]!;
      const value = records[index + 1]!;
      if (key === "PAPERCLIP_GIT_METADATA_ROOT") roots.push(value);
      else if (key === "PAPERCLIP_RUNNER_NETWORK_ROOT") networkRoots.push(value);
      else discovered[key] = value;
    }
    discovered.PAPERCLIP_GIT_METADATA_ROOTS = JSON.stringify([...new Set(roots)]);
    discovered.PAPERCLIP_RUNNER_NETWORK_ROOTS = JSON.stringify([...new Set(networkRoots)]);
  } else {
    const result = await promisify(execFile)(process.execPath, args, { cwd: input.cwd, timeout: 15_000, maxBuffer: 1024 * 1024 });
    try { discovered = JSON.parse(result.stdout.split("\0")[1] ?? ""); }

View on GitHub (pinned to 01ad858492)

Solutions

  1. Confirm the target cwd is a valid Git repository on the remote (`git -C <cwd> status`)
  2. Ensure git is installed and on PATH on the remote target
  3. Run the probe command manually over SSH to inspect raw output and stray banners
  4. Fix or bypass shell init files that emit output before the script runs

Example fix

// verify before invoking
ssh user@remote 'cd <cwd> && git rev-parse --is-inside-work-tree && git --version'
// then retry the operation
Defensive patterns

Strategy: validation

Validate before calling

const st = await runner.execute({ command: 'sh', args: ['-c', `cd ${cwd} && git rev-parse --is-inside-work-tree`], timeoutMs: 10000 });
if (st.exitCode !== 0) throw new Error('target cwd is not a git work tree');

Try / catch

try {
  await prepareGitHubExecutionEnvironment(input);
} catch (e) {
  if (String(e.message).includes('Could not read execution-target Git context')) {
    console.error('verify remote cwd is a git repo and git is installed');
  } else throw e;
}

Prevention

When it happens

Trigger: Remote sh -c probe returns non-zero (git not installed, cwd missing/not a repo, permission issues); shell output lacks the NUL delimiters because a login banner or a different shell swallowed the printf output; probe times out upstream.

Common situations: Running against a directory that is not a Git work tree; remote host without git on PATH; shell profiles printing output that corrupts the framed payload; the managed/host credential mode arg altering script behavior unexpectedly.

Understand the failure class

Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/64b47f9a698c3e38. Report an issue: GitHub.