sgl-project/sglang · error · PatchApplicationError

empty match text

Error message

empty match text

What it means

Raised by source_patcher's _apply_single_edit when an EditSpec's match text is empty (or only whitespace, since it is stripped before the check). An empty match cannot identify any location in the source, so the edit is rejected immediately rather than corrupting the file.

Source

Thrown at python/sglang/srt/debug_utils/source_patcher/source_editor.py:19

from sglang.srt.debug_utils.source_patcher.types import EditSpec, PatchApplicationError


def apply_edits(*, source: str, edits: list[EditSpec]) -> str:
    """Apply a sequence of match/replacement edits to source text.

    Each edit is applied sequentially so later edits see the result of earlier ones.
    """
    result: str = source
    for edit in edits:
        result = _apply_single_edit(source=result, edit=edit)
    return result


def _apply_single_edit(*, source: str, edit: EditSpec) -> str:
    """Apply a single match/replacement edit to the source text."""
    match_text: str = edit.match.strip()
    if not match_text:
        raise PatchApplicationError("empty match text")

    source_lines: list[str] = source.splitlines()
    match_lines: list[str] = match_text.splitlines()

    start_idx: int = _find_match(source_lines=source_lines, match_lines=match_lines)
    match_len: int = len(match_lines)

    original_indent: int = _leading_spaces(source_lines[start_idx])

    effective_replacement: str = _resolve_replacement(edit=edit, match_text=match_text)
    replacement_lines: list[str] = (
        effective_replacement.splitlines() if effective_replacement else []
    )
    aligned: list[str] = _realign_replacement(
        replacement_lines=replacement_lines, original_indent=original_indent
    )
    new_lines: list[str] = (
        source_lines[:start_idx] + aligned + source_lines[start_idx + match_len :]

View on GitHub (pinned to 0132848349)

Solutions

  1. Provide the exact non-empty source lines to match in the EditSpec's match field
  2. If generating specs programmatically, assert match.strip() before applying
  3. Validate patch config files for missing/empty match keys at load time

Example fix

# before
EditSpec(match='', replace='new_code')

# after
EditSpec(match='def old_code():', replace='def new_code():')
Defensive patterns

Strategy: validation

Validate before calling

for spec in specs:
    if not spec.match or not spec.match.strip():
        raise ValueError(f'EditSpec for target has empty match text')

Type guard

def is_non_empty_match(edit) -> bool:
    return bool(getattr(edit, 'match', '') and edit.match.strip())

Try / catch

try:
    new_src = apply_edits(source, [edit])
except PatchApplicationError as e:
    if 'empty match text' in str(e):
        log.error('edit %r has no match text', edit)
        return source  # skip this edit
    raise

Prevention

When it happens

Trigger: Applying an EditSpec built with match='' or match of only whitespace/newlines via apply_edits. Common when match text is generated programmatically (template interpolation producing an empty string) or hand-written YAML with a missing match key defaulting to empty.

Common situations: YAML/JSON patch files with a missing or blank 'match' field; f-string or .format() bugs producing empty match text; trailing-whitespace-only edits that strip to nothing.

Related errors


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