ruvnet/ruflo · error · Error
Git path is not NFC-normalized: ${path}
Error message
Git path is not NFC-normalized: ${path} What it means
Even with valid UTF-8, decodeGitPath requires every tracked path to be in Unicode Normalization Form C (precomposed): path must equal path.normalize('NFC'). macOS filesystems return decomposed (NFD) names for accented characters, so 'café' stored with a combining accent fails the comparison; the offending path is included in the message. Normalization form is part of path identity because paths feed content digests.
Source
Thrown at v3/@claude-flow/codex/src/harness/repository-state.ts:192
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}`);
const normalized = path.normalize('NFC');
if (
normalized.length === 0
|| isAbsolute(normalized)
|| normalized.startsWith('-')
|| normalized.split('/').some((part) => part === '' || part === '.' || part === '..')
) {
throw new Error(`unsafe repository-relative path: ${path}`);
}
return normalized;
}View on GitHub (pinned to fa13ee4ad6)
Solutions
- Rename offenders to NFC: `convmv -r -f nfd -t nfc --notest .` after reviewing the dry run
- Or `git mv` the file to a freshly typed precomposed name
- Normalize user-supplied filenames to NFC at ingestion (name.normalize('NFC')) before writing into the repo
- Add a CI check that rejects NFD paths in git ls-files output
Example fix
// before: filename received from macOS upload, stored decomposed
writeFileSync(`uploads/${userFileName}`, data); // userFileName is NFD
// after: normalize before it touches the repo
writeFileSync(join('uploads', userFileName.normalize('NFC')), data); Defensive patterns
Strategy: try-catch
Validate before calling
function findNonNfcPaths(paths: readonly string[]): string[] {
return paths.filter((p) => p !== p.normalize('NFC'));
} Type guard
function isNfcPath(path: string): boolean {
return path === path.normalize('NFC');
} Try / catch
try {
const state = captureSourceState(repoRoot);
} catch (error) {
if (error instanceof Error && error.message.startsWith('Git path is not NFC-normalized')) {
const path = error.message.slice('Git path is not NFC-normalized: '.length);
throw new Error(`rename to NFC (git mv or convmv -f nfd -t nfc): ${path}`);
}
throw error;
} Prevention
- Run convmv -f nfd -t nfc (dry run first) on repos touched by macOS/iOS clients
- Normalize user-supplied filenames with name.normalize('NFC') before writing them into the repo
- Add a CI scan rejecting decomposed paths in git ls-files output
When it happens
Trigger: Creating or checking out files with diacritics on macOS (NFD) and then running the harness's source-state snapshot; names synced from iOS clients; NFD names committed by a contributor whose editor or FS decomposes accents.
Common situations: Cross-platform teams (macOS NFD vs Linux NFC); cloud-sync folders (iCloud/Dropbox) that decompose names; filenames typed with dead-key input methods that emit combining sequences.
Related errors
- Git path is not valid round-trip UTF-8
- Git returned a non-NUL-terminated path list
- ambiguous repository path separator: ${path}
- Invalid git ref: contains unsafe characters
- Invalid git ref: suspicious pattern
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/c18b912bfd941eca.
Report an issue: GitHub.