can1357/oh-my-pi · error · ParseError
'${firstLine}' is not a valid hunk header. Valid hunk header
Error message
'${firstLine}' is not a valid hunk header. Valid hunk headers: '*** Add File: {path}', '*** Delete File: {path}', '*** Update File: {path}' What it means
Inside a patch, every non-empty line must start a recognized operation: '*** Add File:', '*** Delete File:', or '*** Update File:'. Any other line where a hunk header is expected triggers this ParseError, quoting the offending line and listing valid headers.
Source
Thrown at packages/coding-agent/src/edit/apply-patch/parser.ts:167
lineNumber++;
}
if (diffLines.length === 0) {
if (streaming) {
hunks.push({ path, op: "update", rename: movePath, diff: "" });
continue;
}
throw new ParseError(`Update file hunk for path '${path}' is empty`, lineNumber);
}
hunks.push({ path, op: "update", rename: movePath, diff: diffLines.join("\n") });
continue;
}
if (streaming) {
break;
}
throw new ParseError(
`'${firstLine}' is not a valid hunk header. Valid hunk headers: '*** Add File: {path}', '*** Delete File: {path}', '*** Update File: {path}'`,
lineNumber,
);
}
return hunks;
}
View on GitHub (pinned to 9690622007)
Solutions
- Replace the offending line with one of the valid headers: '*** Add File: {path}', '*** Delete File: {path}', '*** Update File: {path}'
- Strip prose/comments and convert any unified-diff syntax to the codex patch format
- Verify the exact '*** ' prefix and 'Path:'-style header spelling
- Regenerate the patch from the model with format instructions if it keeps emitting invalid headers
Example fix
// before *** Begin Patch --- a/src/a.ts +++ b/src/a.ts // after *** Begin Patch *** Update File: src/a.ts @@ -existing +new *** End Patch
Defensive patterns
Strategy: validation
Validate before calling
const HEADER = /^\*\*\* (Add|Delete|Update) File: .+/;
const body = patchText.split('\n').filter(l => l.trim() && l.trim() !== '*** Begin Patch' && l.trim() !== '*** End Patch');
if (body.some(l => !HEADER.test(l) && !l.startsWith('@@') && !/^[+\- ]/.test(l))) {
throw new SkipOperation('patch contains invalid hunk headers');
} Type guard
function isValidHunkHeader(line) {
return /^\*\*\* (Add|Delete|Update) File: .+/.test(line);
} Try / catch
try {
await applyCodexPatch(patchText);
} catch (err) {
if (err instanceof ParseError && err.message.includes('not a valid hunk header')) {
// show err.message to the user/model: it quotes the offending line
}
} Prevention
- Never mix unified-diff syntax into codex patches
- Strip prose/comments from model output
- Quote the offending line (already in the message) when asking the model to fix the patch
When it happens
Trigger: A line inside the Begin/End markers doesn't match any hunk-header pattern — e.g. prose comments, unified-diff headers (--- a/x, +++ b/x), misspelled markers ('** Update File:'), or stray content between hunks.
Common situations: Model mixed codex-patch format with unified diff syntax; markdown lists or commentary leaked into the patch; typo in the '***' prefix or colon; user hand-edited the patch and broke a header.
Related errors
- The first line of the patch must be '*** Begin Patch'
- Update file hunk for path '${path}' is empty
- The last line of the patch must be '*** End Patch'
- No files were modified.
- patch does not apply: {message}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/7fb5a49ea8a0f0ad.
Report an issue: GitHub.