OpenBMB/ChatDev · error · ValueError
edit ranges overlap; merge them before calling apply_text_ed
Error message
edit ranges overlap; merge them before calling apply_text_edits
What it means
apply_text_edits requires edit ranges to be non-overlapping and sorted ascending; _validate_edit_ranges walks them in order and fails if an edit starts at or before the end of a previous edit (after accounting for pure deletions). Because edits are applied bottom-up in reverse order, overlapping ranges would corrupt positioning, so the library refuses them.
Source
Thrown at functions/function_calling/file.py:956
start_line: int,
end_line: Optional[int],
replacement: Optional[str],
) -> List[Mapping[str, Any]]:
effective_end = end_line if end_line is not None else start_line
payload = {
"start_line": start_line,
"end_line": effective_end,
"replacement": replacement if replacement is not None else "",
}
return [payload]
def _validate_edit_ranges(edits: Sequence[TextEdit]) -> None:
previous_range_end = 0
for edit in edits:
effective_end = max(edit.end_line, edit.start_line - 1)
if edit.start_line <= previous_range_end and previous_range_end > 0:
raise ValueError("edit ranges overlap; merge them before calling apply_text_edits")
previous_range_end = max(previous_range_end, effective_end)
def _apply_edits_in_place(lines: MutableSequence[str], edits: Sequence[TextEdit]) -> None:
for edit in reversed(edits):
current_line_count = len(lines)
if edit.start_line > current_line_count + 1:
raise ValueError("start_line is beyond the end of the file")
start_idx = min(edit.start_line - 1, current_line_count)
if start_idx > current_line_count:
raise ValueError("start_line is beyond the end of the file")
removal_count = max(edit.end_line - edit.start_line + 1, 0)
if removal_count > 0:
end_line = min(edit.end_line, len(lines))
removal_count = max(end_line - edit.start_line + 1, 0)
end_idx = start_idx + removal_count
lines[start_idx:end_idx] = edit.replacement_lines
View on GitHub (pinned to 4fb2db0ea9)
Solutions
- Merge overlapping edits into a single edit covering the union range with the combined replacement text
- Sort edits by start_line ascending and verify ranges do not touch/overlap before calling
- Recompute edit ranges from the original file snapshot rather than incrementally from prior edits
Example fix
# before
edits=[{"start_line": 3, "end_line": 5, "replacement": "a"},
{"start_line": 4, "end_line": 6, "replacement": "b"}]
# after
edits=[{"start_line": 3, "end_line": 6, "replacement": "a\nb"}] Defensive patterns
Strategy: validation
Validate before calling
def merge_overlaps(edits):
edits = sorted(edits, key=lambda e: e["start_line"])
merged = []
for e in edits:
if merged and e["start_line"] <= merged[-1].get("end_line", merged[-1]["start_line"]):
prev = merged.pop()
e = {"start_line": prev["start_line"],
"end_line": max(e.get("end_line", 0), prev.get("end_line", 0)),
"replacement": e.get("replacement", "")}
merged.append(e)
return merged
apply_text_edits(path=path, edits=merge_overlaps(edits)) Type guard
def edits_disjoint_and_sorted(edits) -> bool:
prev_end = 0
for e in sorted(edits, key=lambda x: x["start_line"]):
end = max(e.get("end_line", e["start_line"]), e["start_line"] - 1)
if e["start_line"] <= prev_end > 0:
return False
prev_end = max(prev_end, end)
return True Try / catch
try:
apply_text_edits(path=path, edits=edits)
except ValueError as e:
if "overlap" in str(e):
apply_text_edits(path=path, edits=merge_overlaps(edits))
else:
raise Prevention
- Sort and de-duplicate hunks before submitting
- Apply all edits in one batch from a single file snapshot
- Recompute ranges after any prior edit instead of reusing stale ones
When it happens
Trigger: Two edits touching the same lines, e.g. (3-5) and (4-6); edits generated out of ascending order; edits derived from multiple diff hunks that share a boundary line.
Common situations: Merging hunks from a patch file without de-duplicating; LLM emitting redundant overlapping edits; adding an edit at the end of a list that should have been merged with an earlier one.
Related errors
- at least one edit instruction is required
- each edit entry must be a mapping object
- start_line is required for each edit
- end_line must be an integer
- end_line must be >= start_line - 1
AI-assisted analysis of OpenBMB/ChatDev@4fb2db0ea9 (2026-08-27).
Data as JSON: /api/errors/02315db9b40f1f52.
Report an issue: GitHub.