Skip to content

More or fewer (less frequent) indentation for "added" lines of edits (apply_patch tool calls) #28147

@Func86

Description

@Func86

What version of Codex CLI is running?

codex-cli 0.139.0

What subscription do you have?

Pro Lite

Which model were you using?

gpt-5.5 (reasoning xhigh, summaries detailed)

What platform is your computer?

Linux 6.6.114.1-microsoft-standard-WSL2 x86_64 unknown

What terminal emulator and version are you using (if applicable)?

Windows Terminal

Codex doctor report

What issue are you seeing?

Image

There is a pattern that it almost always gets the "removed" lines right, but with more or fewer (less frequent) indentation for "added" lines.

I have a workaround for this issue with instructions about using ESLint autofix for weeks, but it's just annoying and wastes time for every round.

Is this a model or harness issue? Is it encouraged or rewarded for more "complex" code (thus more indentations as a result)?

› Why would you get and only get the indentation wrong on the "added" part?


• Because the - side usually comes from the existing file, while the + side is authored by me.

  A typical workflow is:

  1. Read or search the existing line.
  2. Put that exact existing line into the patch as -....
  3. Write the new version as +....

  Step 2 preserves the file’s indentation because it was copied from the file. Step 3 is where I can miscount nesting or type one tab too many/few,
  especially in deep JSX.

  Example:

  -                                             <Button variant="primary" type="submit">
  +                                                     <Button loading={saving} variant="primary" type="submit">

  The removed line is exact because it came from the file. The added line is wrong because I manually inserted an extra tab while adding loading.

  When I replaced whole blocks, I also manually authored + versions of child and closing lines. Those could be wrong too, even though the matching - block
  was exact.


› What do you mean by "put"? It sounds mechanical, but is it?


• By “put,” I mean I construct the patch text that gets sent to apply_patch.

  It is partly mechanical, but not automatically safe. I usually read the file, then write a patch hunk like:

  -<old line copied from file>
  +<new line I want>

  The old line is often copied or closely transcribed from the file output, so it tends to be exact. The new line is authored by me, so indentation can be
  wrong if I misread the nesting or add a tab while editing.

  The tool itself is mechanical: it applies the patch text exactly. The weak point is me composing the patch text. For indentation-sensitive JSX, the safer
  approach is to change the smallest possible line and then run ESLint/formatter, which is what I should bias toward.


› You are authoring the patch as a whole, or really step-by-step?


• I author the patch as a whole message to the tool, not interactively step by step.

  But while composing it, there are two different sources in practice:

  - - lines are based on the current file text I just inspected, so they are usually copied/transcribed from known content.
  - + lines are the new text I generate, so they carry more risk for indentation or wrapping mistakes.

  apply_patch then receives the whole patch at once and applies or rejects it. It does not guide me line by line.


› No, I mean, when you author the patch as a whole, you should be aware that "the change is small and very localized, no indentation change is expected",
  right? There is a pattern that you almost always get the "removed" lines right, but with more (usually) or fewer indentation for "added" lines. Why?


• Yes, I should be aware of that. For a localized prop change, any indentation change is a defect unless the surrounding syntax forces reflow.

  The reason the pattern shows up is that I’m preserving the old line as an anchor but regenerating the new line from the semantic structure, not doing a
  literal “same leading whitespace + modified contents” transform. That means I can correctly identify:

                                                        <Button variant="primary" type="submit">

  then generate the replacement from my mental model of the JSX depth:

                                                                <Button loading={saving} variant="primary" type="submit">

  The semantic change is right, but the leading whitespace was recomputed incorrectly. That is the bug.

  For this kind of edit, the right discipline is: preserve the exact leading whitespace from the removed line, and change only the interior text. For
  example:

  -                                                     <Button variant="primary" type="submit">
  +                                                     <Button loading={saving} variant="primary" type="submit">

  not:

  -                                                     <Button variant="primary" type="submit">
  +                                                             <Button loading={saving} variant="primary" type="submit">

  So the answer is: the old line is grounded in observed file text; the new line is sometimes regenerated with guessed indentation. I should avoid guessing
  indentation for localized edits.

What steps can reproduce the bug?

Uploaded thread: 019ec3af-5511-7db2-bd7b-95f3ccd62455

What is the expected behavior?

No response

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    CLIIssues related to the Codex CLIbugSomething isn't workingmodel-behaviorIssues related to behaviors exhibited by the modeltool-callsIssues related to tool calling

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions