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

  1. Replace the offending line with one of the valid headers: '*** Add File: {path}', '*** Delete File: {path}', '*** Update File: {path}'
  2. Strip prose/comments and convert any unified-diff syntax to the codex patch format
  3. Verify the exact '*** ' prefix and 'Path:'-style header spelling
  4. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/7fb5a49ea8a0f0ad. Report an issue: GitHub.