{"record":{"id":"2388b48f2e047db3","repo":"sgl-project/sglang","slug":"empty-match-text","errorCode":null,"errorMessage":"empty match text","messagePattern":"empty match text","errorType":"exception","errorClass":"PatchApplicationError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/debug_utils/source_patcher/source_editor.py","lineNumber":19,"sourceCode":"from sglang.srt.debug_utils.source_patcher.types import EditSpec, PatchApplicationError\n\n\ndef apply_edits(*, source: str, edits: list[EditSpec]) -> str:\n    \"\"\"Apply a sequence of match/replacement edits to source text.\n\n    Each edit is applied sequentially so later edits see the result of earlier ones.\n    \"\"\"\n    result: str = source\n    for edit in edits:\n        result = _apply_single_edit(source=result, edit=edit)\n    return result\n\n\ndef _apply_single_edit(*, source: str, edit: EditSpec) -> str:\n    \"\"\"Apply a single match/replacement edit to the source text.\"\"\"\n    match_text: str = edit.match.strip()\n    if not match_text:\n        raise PatchApplicationError(\"empty match text\")\n\n    source_lines: list[str] = source.splitlines()\n    match_lines: list[str] = match_text.splitlines()\n\n    start_idx: int = _find_match(source_lines=source_lines, match_lines=match_lines)\n    match_len: int = len(match_lines)\n\n    original_indent: int = _leading_spaces(source_lines[start_idx])\n\n    effective_replacement: str = _resolve_replacement(edit=edit, match_text=match_text)\n    replacement_lines: list[str] = (\n        effective_replacement.splitlines() if effective_replacement else []\n    )\n    aligned: list[str] = _realign_replacement(\n        replacement_lines=replacement_lines, original_indent=original_indent\n    )\n    new_lines: list[str] = (\n        source_lines[:start_idx] + aligned + source_lines[start_idx + match_len :]","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/debug_utils/source_patcher/source_editor.py#L1-L37","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Provide the exact non-empty source lines to match in the EditSpec's match field","If generating specs programmatically, assert match.strip() before applying","Validate patch config files for missing/empty match keys at load time"],"exampleFix":"# before\nEditSpec(match='', replace='new_code')\n\n# after\nEditSpec(match='def old_code():', replace='def new_code():')","handlingStrategy":"validation","validationCode":"for spec in specs:\n    if not spec.match or not spec.match.strip():\n        raise ValueError(f'EditSpec for target has empty match text')","typeGuard":"def is_non_empty_match(edit) -> bool:\n    return bool(getattr(edit, 'match', '') and edit.match.strip())","tryCatchPattern":"try:\n    new_src = apply_edits(source, [edit])\nexcept PatchApplicationError as e:\n    if 'empty match text' in str(e):\n        log.error('edit %r has no match text', edit)\n        return source  # skip this edit\n    raise","preventionTips":["Never build EditSpec from unvalidated interpolation","Add schema validation for patch YAML requiring a non-empty match","Unit-test patch generators to reject empty matches"],"tags":["patching","validation","source-patcher","sglang"],"backgroundTag":"empty-match-pattern","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}