sgl-project/sglang · error · PatchApplicationError
match text found multiple times ({len(found_indices)} occurr
Error message
match text found multiple times ({len(found_indices)} occurrences) in source:\n{preview} What it means
Raised by the source patcher when the `match` text given in an edit is found more than once in the target source. The patcher applies edits by exact (stripped) text matching and requires the match to be unique so it can locate a single anchor line, so multiple occurrences make the edit ambiguous.
Source
Thrown at python/sglang/srt/debug_utils/source_patcher/source_editor.py:75
Raises PatchApplicationError if not found or found multiple times.
"""
stripped_source: list[str] = [line.strip() for line in source_lines]
stripped_match: list[str] = [line.strip() for line in match_lines]
match_len: int = len(stripped_match)
found_indices: list[int] = [
i
for i in range(len(stripped_source) - match_len + 1)
if stripped_source[i : i + match_len] == stripped_match
]
if len(found_indices) == 0:
raise PatchApplicationError(
_not_found_diagnostic(stripped_source, stripped_match)
)
if len(found_indices) > 1:
preview = "\n".join(match_lines)
raise PatchApplicationError(
f"match text found multiple times ({len(found_indices)} occurrences) in source:\n{preview}"
)
return found_indices[0]
def _not_found_diagnostic(stripped_source: list[str], stripped_match: list[str]) -> str:
preview = "\n".join(stripped_match)
lines = [
f"match text not found in source:\n{preview}",
"",
f"source_len={len(stripped_source)} lines",
]
if not stripped_match:
return "\n".join(lines)
first_match_line = stripped_match[0]
hits = [i for i, line in enumerate(stripped_source) if line == first_match_line]View on GitHub (pinned to 0132848349)
Solutions
- Enlarge the `match` text to include unique surrounding lines (e.g. the def line plus the first body statement) so only one occurrence exists
- Check the preview in the error message to see all matching lines and pick distinguishing context to add
- If you intend to replace all occurrences, split the source or apply edits one region at a time with unique anchors
Example fix
// before edit = Edit(match="return None", replacement="return 0") # 'return None' appears 3x // after edit = Edit(match="def calc(self):\n return None", replacement="def calc(self):\n return 0")
Defensive patterns
Strategy: validation
Validate before calling
stripped = source.replace('\\r\\n','\\n').strip()\ncount = stripped.count(match_text.strip())\nassert count == 1, f'match appears {count} times; extend match text with unique context' Try / catch
from sglang.srt.debug_utils.source_patcher.source_editor import PatchApplicationError\ntry:\n editor.apply(edit)\nexcept PatchApplicationError as e:\n # message lists all occurrences; widen `edit.match` and retry once\n edit = edit.with_larger_match(context_lines=2)\n editor.apply(edit)
Prevention
- Always include a unique anchor line (e.g. the def/class statement) in match text
- Run a uniqueness count on the match string before applying the patch
- Keep match snippets at least a few lines long in repetitive files
When it happens
Trigger: Calling _apply_single_edit (e.g. via a SourceEditor apply/patch API) with a `match` string that appears 2+ times in the file after whitespace stripping. The error message previews every matching line so you can disambiguate.
Common situations: Patching boilerplate that repeats across a file, such as multiple identical function signatures, repeated `return None` lines, or duplicated import blocks; also matching a too-short snippet (e.g. a bare decorator or blank-line-adjacent line).
Related errors
- Multiple serve backends matched this request: {names}. Selec
- op {op!r} has multiple backends usable on device {platform.d
- Unknown serve backend {name!r}. Available values: {available
- Multiple distributions register serve backend {name!r}: {pro
- Failed to load serve backend {name!r} from {self._entry_poin
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/3e8a6baae649c542.
Report an issue: GitHub.