{"record":{"id":"112ab66c62cd3622","repo":"ruvnet/ruflo","slug":"git-path-is-not-valid-round-trip-utf-8","errorCode":null,"errorMessage":"Git path is not valid round-trip UTF-8","messagePattern":"Git path is not valid round-trip UTF-8","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/codex/src/harness/repository-state.ts","lineNumber":188,"sourceCode":"  }\n}\n\nfunction splitNul(output: Buffer): Buffer[] {\n  const records: Buffer[] = [];\n  let start = 0;\n  for (let index = 0; index < output.length; index += 1) {\n    if (output[index] !== 0) continue;\n    if (index > start) records.push(output.subarray(start, index));\n    start = index + 1;\n  }\n  if (start !== output.length) throw new Error('Git returned a non-NUL-terminated path list');\n  return records;\n}\n\nfunction decodeGitPath(bytes: Buffer): string {\n  const path = bytes.toString('utf8');\n  if (!Buffer.from(path, 'utf8').equals(bytes)) {\n    throw new Error('Git path is not valid round-trip UTF-8');\n  }\n  assertUnicodeScalarString(path);\n  if (path !== path.normalize('NFC')) {\n    throw new Error(`Git path is not NFC-normalized: ${path}`);\n  }\n  return normalizeRelativePath(path);\n}\n\nfunction normalizeRelativePath(path: string): string {\n  assertUnicodeScalarString(path);\n  if (path.includes('\\\\')) throw new Error(`ambiguous repository path separator: ${path}`);\n  const normalized = path.normalize('NFC');\n  if (\n    normalized.length === 0\n    || isAbsolute(normalized)\n    || normalized.startsWith('-')\n    || normalized.split('/').some((part) => part === '' || part === '.' || part === '..')\n  ) {","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/codex/src/harness/repository-state.ts#L170-L206","documentation":"decodeGitPath round-trips the raw bytes: bytes decoded as UTF-8 must re-encode to the identical bytes. Invalid UTF-8 byte sequences (typically latin-1/cp1252 filenames from legacy systems) decode to U+FFFD replacement characters and fail the round trip. Trusting such names would hash corrupted bytes, so the harness refuses them.","triggerScenarios":"A tracked filename containing invalid UTF-8 bytes — created on Windows with a legacy code page, extracted from an archive with the wrong filename encoding, or written by a tool that emits raw byte names on a filesystem that permits them (ext4).","commonSituations":"Repos migrated from Windows machines; zip/tar extraction with mislabeled encodings; files created by older Java/Perl tools that wrote byte names; contributors on mixed-encoding systems.","solutions":["Identify offenders: dump `git -C <repo> ls-files -z | od -c` and look for non-UTF-8 byte sequences, or scan decoded names for U+FFFD","Rename each offender with git mv to a valid UTF-8 name","Batch-fix whole trees with convmv: `convmv -r -f latin1 -t utf8 --notest .` (dry-run first without --notest)","Re-extract source archives with the correct filename encoding instead of committing mangled names"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import { execFileSync } from 'node:child_process';\nfunction findNonUtf8Paths(repoRoot: string): string[] {\n  const out = execFileSync('git', ['-C', repoRoot, 'ls-files', '-z'], { encoding: 'buffer' });\n  return out.toString('utf8').split('\\u0000')\n    .filter((p) => p.includes('\\uFFFD'));\n}","typeGuard":"function isRoundTripUtf8(path: string): boolean {\n  return Buffer.from(path, 'utf8').equals(Buffer.from(path, 'utf8')) && !path.includes('\\uFFFD');\n}","tryCatchPattern":"try {\n  const state = captureSourceState(repoRoot);\n} catch (error) {\n  if (error instanceof Error && error.message === 'Git path is not valid round-trip UTF-8') {\n    const offenders = findNonUtf8Paths(repoRoot);\n    throw new Error(`non-UTF-8 filenames need renaming (git mv): ${offenders.join(', ')}`);\n  }\n  throw error;\n}","preventionTips":["Rename legacy-encoded filenames to valid UTF-8 before committing (git mv)","Extract archives with the correct filename encoding option","Add a CI check rejecting U+FFFD in git ls-files output"],"tags":["git","utf-8","filename","filesystem","repository-state"],"backgroundTag":"invalid-utf8-filename","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}