Skip to content

apply_patch silently drops a file section whose header is indented, and reports success #45

Description

@code-yeongyu

Summary

apply_patch can report success while silently dropping a whole file section. Between file sections, the parser skips any line that does not start with *** (no leading whitespace). A file header indented by a space or two is skipped, and so are all of its @@ / - / + lines. The tool then returns success for the sections it did parse, and the model believes the skipped file was edited.

Reproduction

// old.txt = "x\n", b.txt = "b1\n"
await applyPatchDetailed(cwd, "*** Begin Patch\n*** Delete File: old.txt\n  *** Update File: b.txt\n@@\n-b1\n+B1\n*** End Patch\n")
// -> { summaries: ["delete: old.txt"], failures: [] }; b.txt is still "b1\n"

The same indented header as the first section fails with the misleading apply_patch verification failed: no hunks found. Codex's portable conformance scenario 017_whitespace_padded_hunk_header (codex-rs/apply-patch/tests/fixtures/scenarios/) fails on this package.

Expected

Match Codex (codex-rs/apply-patch/src/streaming_parser.rs, process_line, at b741e48):

  • File headers are recognized after trimming, so an indented *** Update File: header applies.
  • Any other non-blank line between file sections rejects the whole patch with '<line>' is not a valid hunk header. Nothing is applied and success is never reported.
  • Inside an update hunk, an indented marker stays a context line (unchanged; Codex keeps it as context too).

Actual

The section is silently dropped and the result reports success.

Acceptance

  • Codex scenario 017 passes.
  • An indented header after a Delete section or after Add File content still applies.
  • A stray line between sections rejects the patch and leaves every file unchanged.

Activity

  1. code-yeongyu commented on Oct 3, 2026

    @code-yeongyu
    OwnerAuthor

    Fixed by #46, merged as f916a8e.

    • Headers: file headers are read after trimming, as in Codex. Any other non-blank line between file sections rejects the patch before anything applies.
    • Shared parsing: the parser and extractPatchedPaths read headers through one helper, so listed paths are exactly the written paths for any whitespace padding, a no-break space included.
    • Evidence:
      • test/patch-headers.test.ts: 7 cases, 6 of them failing on the pre-fix code;
      • full suite 68/68 and CI green on 36388ed;
      • Codex's portable scenario 017_whitespace_padded_hunk_header now passes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions