openai/codex · error · ParseError
invalid hunk at line {line_number}, {message}
Error message
invalid hunk at line {line_number}, {message} What it means
Hunk-level syntax error: the patch as a whole parsed, but one hunk violates the grammar. Display embeds the 1-based line_number within the patch text and a message naming the violation - for example a change line missing its leading ' ', '+', or '-' prefix, an Update File hunk with no context/changes, a misplaced '*** End of File', or a malformed '*** Move to:'. Lenient mode tolerates gpt-4.1 quirks, so this variant indicates real structural damage inside a hunk.
Source
Thrown at codex-rs/apply-patch/src/parser.rs:59
pub(crate) const UPDATE_FILE_MARKER: &str = "*** Update File: ";
pub(crate) const MOVE_TO_MARKER: &str = "*** Move to: ";
pub(crate) const EOF_MARKER: &str = "*** End of File";
pub(crate) const CHANGE_CONTEXT_MARKER: &str = "@@ ";
pub(crate) const EMPTY_CHANGE_CONTEXT_MARKER: &str = "@@";
/// Currently, the only OpenAI model that knowingly requires lenient parsing is
/// gpt-4.1. While we could try to require everyone to pass in a strictness
/// param when invoking apply_patch, it is a pain to thread it through all of
/// the call sites, so we resign ourselves allowing lenient parsing for all
/// models. See [`ParseMode::Lenient`] for details on the exceptions we make for
/// gpt-4.1.
const PARSE_IN_STRICT_MODE: bool = false;
#[derive(Debug, PartialEq, Error, Clone)]
pub enum ParseError {
#[error("invalid patch: {0}")]
InvalidPatchError(String),
#[error("invalid hunk at line {line_number}, {message}")]
InvalidHunkError { message: String, line_number: usize },
}
use ParseError::*;
#[derive(Debug, PartialEq, Clone)]
#[allow(clippy::enum_variant_names)]
pub enum Hunk {
AddFile {
path: PathBuf,
contents: String,
},
DeleteFile {
path: PathBuf,
},
UpdateFile {
path: PathBuf,
move_path: Option<PathBuf>,
View on GitHub (pinned to 339751715c)
Solutions
- Go to the reported line_number in the patch text and fix the violation named in the message
- Verify every change line inside Update hunks starts with ' ', '+', or '-'
- Ensure the final line of the patch ends with a newline
- Regenerate the patch from the model or tool rather than hand-editing hunk syntax
Example fix
# before (line reported invalid: context line missing its leading space)
*** Update File: a.txt
@@ def main():
print("hi")
# after
*** Update File: a.txt
@@ def main():
print("hi") Defensive patterns
Strategy: try-catch
Type guard
fn is_invalid_hunk(e: &ParseError) -> bool {
matches!(e, ParseError::InvalidHunkError { .. })
} Try / catch
if let ApplyPatchError::ParseError(ParseError::InvalidHunkError { message, line_number }) = inner {
// surface line_number to the user/model so the hunk can be self-corrected
eprintln!("bad hunk at patch line {line_number}: {message}");
} Prevention
- End patch text with a trailing newline so the last hunk line is not cut
- Never hand-edit hunk line prefixes when modifying a patch
- Feed parser errors with line numbers back to the generating model for self-correction
When it happens
Trigger: A change line inside an Update hunk missing its context/add/remove prefix; an '*** Update File:' section with no @@ context or change lines; '*** End of File' used inside an Add hunk; the final patch line missing its trailing newline so the last hunk line is cut.
Common situations: A model emits hunk bodies with wrong prefixes; hand-edits damage a hunk; CRLF or whitespace mangling; copy-paste drops leading spaces on context lines.
Related errors
- invalid patch: {0}
- {error}
- No files were modified.
- InvalidInput
- Unsupported platform: ${platform} (${arch})
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/ddeece286c656942.
Report an issue: GitHub.