openai/codex · error · ApplyPatchFailure

{error}

Error message

{error}

What it means

Top-level error returned by the apply_patch family (apply_patch, apply_patch_with_options, apply_hunks). Its Display forwards to the wrapped ApplyPatchError, so the visible message comes from the underlying cause: a parse error, an IO error, a failed hunk context match, or even a failure writing the summary to stdout/stderr. The payload's real value is the AppliedPatchDelta it carries alongside the error: the ordered list of file mutations that were definitely committed to disk before the failure was observed, intended for undo/rollback.

Source

Thrown at codex-rs/apply-patch/src/lib.rs:313

    Add {
        content: String,
        overwritten_content: Option<String>,
    },
    Delete {
        content: String,
    },
    Update {
        move_path: Option<PathUri>,
        old_content: String,
        overwritten_move_content: Option<String>,
        new_content: String,
    },
}

/// A failed patch application together with the textual mutations that were
/// definitely committed before the failure was observed.
#[derive(Debug, Error)]
#[error("{error}")]
pub struct ApplyPatchFailure {
    #[source]
    error: ApplyPatchError,
    delta: AppliedPatchDelta,
}

impl ApplyPatchFailure {
    fn new(error: ApplyPatchError, delta: AppliedPatchDelta) -> Self {
        Self { error, delta }
    }

    fn without_delta(error: ApplyPatchError) -> Self {
        Self::new(error, AppliedPatchDelta::empty())
    }

    pub fn delta(&self) -> &AppliedPatchDelta {
        &self.delta
    }

View on GitHub (pinned to 339751715c)

Solutions

  1. Call into_parts() (or delta()) on the failure and use the returned AppliedPatchDelta to undo changes already committed before propagating the error
  2. Inspect the inner ApplyPatchError for the real cause - the printed message is the inner error's text, not this wrapper's
  3. If the delta is empty, nothing was modified; fix the patch itself (see the inner ParseError or IO cause) and re-apply the whole patch
  4. Re-read the target files and regenerate the patch so hunk contexts match current contents

Example fix

// before
if let Err(failure) = apply_patch(patch, &cwd, &mut stdout, &mut stderr, fs, None).await {
    eprintln!("patch failed: {failure}"); // loses partial-change info
}

// after
if let Err(failure) = apply_patch(patch, &cwd, &mut stdout, &mut stderr, fs, None).await {
    let (err, applied) = failure.into_parts();
    eprintln!("patch failed: {err}; {} change(s) already committed", applied.changes.len());
    for change in applied.changes {
        // restore old content recorded in `change.change` before propagating
    }
}
Defensive patterns

Strategy: try-catch

Try / catch

match apply_patch(patch, &cwd, &mut stdout, &mut stderr, fs, sandbox).await {
    Ok(delta) => { /* success */ }
    Err(failure) => {
        let (err, applied) = failure.into_parts();
        // rollback the changes recorded in `applied` before propagating
        return Err(err.into());
    }
}

Prevention

When it happens

Trigger: Any call to apply_patch/apply_patch_with_options/apply_hunks that fails: an Update File hunk whose context lines do not match the file on disk, an Add File onto an unwritable path, an unparseable patch (wrapped as ApplyPatchError::ParseError with an empty delta), or a failure writing the result summary. Multi-hunk patches that fail midway return it with a non-empty delta of already-applied changes.

Common situations: Applying model-generated patches against files that changed since the patch was computed; concurrent edits between read and write; permission or ENOSPC failures mid-write; truncated model output that fails parsing before anything is applied (empty delta).

Related errors


AI-assisted analysis of openai/codex@339751715c (2026-08-25). Data as JSON: /api/errors/9175ca33823e1518. Report an issue: GitHub.