ruvnet/ruflo · error · Error
Git returned a non-NUL-terminated path list
Error message
Git returned a non-NUL-terminated path list
What it means
splitNul parses stdout of git listing commands run with -z (git ls-files -z, ls-files --stage -z, and similar via execFileSync). Every record must be NUL-terminated; a trailing non-empty segment after the last NUL means the output does not conform to the -z contract — truncated, reformatted, or produced by something other than stock git. The check runs before paths are trusted for source-state digests.
Source
Thrown at v3/@claude-flow/codex/src/harness/repository-state.ts:181
function optionalGitText(repoRoot: string, args: readonly string[]): string | undefined {
try {
const value = gitText(repoRoot, args);
return value.length > 0 ? value : undefined;
} catch {
return undefined;
}
}
function splitNul(output: Buffer): Buffer[] {
const records: Buffer[] = [];
let start = 0;
for (let index = 0; index < output.length; index += 1) {
if (output[index] !== 0) continue;
if (index > start) records.push(output.subarray(start, index));
start = index + 1;
}
if (start !== output.length) throw new Error('Git returned a non-NUL-terminated path list');
return records;
}
function decodeGitPath(bytes: Buffer): string {
const path = bytes.toString('utf8');
if (!Buffer.from(path, 'utf8').equals(bytes)) {
throw new Error('Git path is not valid round-trip UTF-8');
}
assertUnicodeScalarString(path);
if (path !== path.normalize('NFC')) {
throw new Error(`Git path is not NFC-normalized: ${path}`);
}
return normalizeRelativePath(path);
}
function normalizeRelativePath(path: string): string {
assertUnicodeScalarString(path);
if (path.includes('\\')) throw new Error(`ambiguous repository path separator: ${path}`);View on GitHub (pinned to fa13ee4ad6)
Solutions
- Run `git --version` and `command -v git` from the same environment the harness runs in; remove any wrapper/shim so the real git binary is invoked
- Reproduce manually: `git -C <repo> ls-files -z | od -c | tail -3` and confirm the output ends with \\0
- Unset interfering git env/config for the harness process (GIT_ALIASES, advice, aliases defined in .gitconfig)
- If stock git reproduces it, capture git version and a byte dump and report it to maintainers
Defensive patterns
Strategy: try-catch
Validate before calling
import { execFileSync } from 'node:child_process';
function preflightGitNulTermination(repoRoot: string): void {
const out = execFileSync('git', ['-C', repoRoot, 'ls-files', '-z'], { encoding: 'buffer', maxBuffer: 1024 * 1024 * 512 });
if (out.length > 0 && out[out.length - 1] !== 0) {
throw new Error(`git on PATH is not emitting NUL-terminated listings; check: ${execFileSync('which', ['git']).toString().trim()}`);
}
} Try / catch
try {
const state = captureSourceState(repoRoot);
} catch (error) {
if (error instanceof Error && error.message === 'Git returned a non-NUL-terminated path list') {
throw new Error(`git output malformed (PATH shim or truncated stdout?): git = ${process.env.PATH}`);
}
throw error;
} Prevention
- Run `command -v git` and `git --version` in the harness environment; remove wrappers/shims from PATH
- Do not pipe git output through text tools or aliases that strip NUL bytes
- Keep git reasonably current and free of hooks/aliases that write to stdout
When it happens
Trigger: A 'git' shim earlier on PATH (wrapper scripts, node_modules/.bin, PATH routers) that reformats output or drops -z; stdout truncated mid-path; git aliases/hooks printing advice or progress to stdout; a git build whose ls-files output omits the final NUL.
Common situations: Corporate machines with git wrappers; environment PATH shims intercepting git; large repos where output streams get truncated; environments with aggressive git config (aliases, advice) inherited from dotfiles.
Related errors
- Git path is not valid round-trip UTF-8
- Git path is not NFC-normalized: ${path}
- ambiguous repository path separator: ${path}
- case-fold repository path collision: ${prior} and ${path}
- unsupported untracked repository entry: ${path}
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/3035d60d83705d1c.
Report an issue: GitHub.