Skip to content

Edit tool strips leading whitespace from first line of replacement block #29573

@Javier-Rivasseau

Description

@Javier-Rivasseau

Bug Report

Discovered by: Javier-Rivasseau/SOP-3.0 project

Description

The edit tool strips leading whitespace from the first line of the newString replacement block. This causes silent indentation corruption in Python files, where indentation IS logic.

Reproduction

Given a file with content at indent level 12 (3 levels x 4 spaces):

            if condition:
                result = calculate()
                return result

Using the edit tool to replace those 3 lines with a new block at the same indent level:

oldString: "            if condition:\n                result = calculate()\n                return result"
newString: "            if condition:\n                new_result = calculate_v2()\n                return new_result"

Expected: All lines maintain indent=12/16 as written in newString.

Actual: The first line loses 4 spaces — indent becomes 8 instead of 12:

        if condition:           # indent=8, should be 12
            new_result = calculate_v2()  # indent=12, correct
            return new_result            # indent=12, correct

Impact

In Python, this is fatal — it changes code semantics, breaks try/except blocks, causes UnboundLocalError when variables end up outside their scope, and can move code into or out of conditional blocks.

In our project (a ~8,000-line Python stock scanner), this single bug caused 7 production incidents across v10.29-v10.68, each requiring emergency hotfixes:

Version Bug caused by edit tool indentation corruption Severity
v10.29.1 Defensive defaults at indent 0 instead of 8 -> UnboundLocalError for 3 tickers CRITICAL
v10.29.2 80 lines dedented by 4 spaces -> code swallowed inside except block -> UnboundLocalError for 188 tickers CRITICAL
v10.44.1 Logger line at indent 8 instead of 12 -> UnboundLocalError for 25/181 tickers -> 0 COMPRAs CRITICAL
v10.57 RevGrowth else: at indent 8 instead of 12 -> false penalty log on ALL tickers CRITICAL
v10.59.1 eps UnboundLocalError — indent 8 instead of 12 in DCF cross-validation CRITICAL
v10.68 IV Rank display insertion — first line lost indent MEDIUM

Workaround

We now use Python scripts with str.replace() or line-index replacement instead of the edit tool for any change >3 lines. We also run a custom validate_scanner.py (AST parse + indentation integrity check) before and after every edit.

Suggested Fix

Preserve the exact leading whitespace of newString as written. Do not strip, trim, or normalize whitespace on the replacement block. If the user writes 12 leading spaces, the tool should insert 12 leading spaces.

Environment

  • OpenCode CLI (latest)
  • Python 3.12.3 on WSL2 (Ubuntu)
  • File type: .py (whitespace-sensitive language)

Metadata

Metadata

Assignees

Labels

No labels
No labels

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