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

  1. Enlarge the `match` text to include unique surrounding lines (e.g. the def line plus the first body statement) so only one occurrence exists
  2. Check the preview in the error message to see all matching lines and pick distinguishing context to add
  3. 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

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


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/3e8a6baae649c542. Report an issue: GitHub.