{"record":{"id":"830e59a25d55fde8","repo":"sgl-project/sglang","slug":"match-text-not-found-in-source-n-preview-n-nsour","errorCode":null,"errorMessage":"match text not found in source:\\n{preview}\\n\\nsource_len={len(stripped_source)} lines","messagePattern":"match text not found in source:\\\\n(.+?)\\\\n\\\\nsource_len=(.+?) lines","errorType":"exception","errorClass":"PatchApplicationError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/debug_utils/source_patcher/source_editor.py","lineNumber":70,"sourceCode":"\ndef _find_match(*, source_lines: list[str], match_lines: list[str]) -> int:\n    \"\"\"Find the start index of match_lines in source_lines (strip-compared).\n\n    Returns the index of the first matching line.\n    Raises PatchApplicationError if not found or found multiple times.\n    \"\"\"\n    stripped_source: list[str] = [line.strip() for line in source_lines]\n    stripped_match: list[str] = [line.strip() for line in match_lines]\n    match_len: int = len(stripped_match)\n\n    found_indices: list[int] = [\n        i\n        for i in range(len(stripped_source) - match_len + 1)\n        if stripped_source[i : i + match_len] == stripped_match\n    ]\n\n    if len(found_indices) == 0:\n        raise PatchApplicationError(\n            _not_found_diagnostic(stripped_source, stripped_match)\n        )\n    if len(found_indices) > 1:\n        preview = \"\\n\".join(match_lines)\n        raise PatchApplicationError(\n            f\"match text found multiple times ({len(found_indices)} occurrences) in source:\\n{preview}\"\n        )\n\n    return found_indices[0]\n\n\ndef _not_found_diagnostic(stripped_source: list[str], stripped_match: list[str]) -> str:\n    preview = \"\\n\".join(stripped_match)\n    lines = [\n        f\"match text not found in source:\\n{preview}\",\n        \"\",\n        f\"source_len={len(stripped_source)} lines\",\n    ]","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/debug_utils/source_patcher/source_editor.py#L52-L88","documentation":"Raised by _find_match when the (whitespace-stripped) match lines from an EditSpec appear nowhere in the (whitespace-stripped) source lines. The message embeds a diagnostic preview plus source length to help locate near-misses. Matching is line-based and indentation-insensitive, but content must match exactly otherwise.","triggerScenarios":"Calling apply_edits with an EditSpec whose match text does not correspond to any contiguous block of lines in the target source — stale match text after the file changed, wrong file targeted, or subtle content differences (comments, renamed identifiers, spacing inside lines).","commonSituations":"Source file was edited/upgraded after the patch was written, so match text is stale; patch YAML targets a different sglang version's source; subtle diffs like changed keyword-arg names or split lines; tabs vs spaces normalized only per-line-stripped but intra-line whitespace still differs.","solutions":["Open the target file and copy the exact current lines into the match field","Re-run the patch pipeline that generated the spec against the current source version","Check the diagnostic preview in the message for near-miss lines (often reveals a one-word difference)","Pin the sglang version the patch was authored against, or regenerate patches on upgrade"],"exampleFix":"# before\nEditSpec(match='x = attention_old(input)', replace='x = attention_new(input)')\n# source actually contains: x = attention_ref(input)\n\n# after\nEditSpec(match='x = attention_ref(input)', replace='x = attention_new(input)')","handlingStrategy":"validation","validationCode":"def strip_lines(text: str) -> list[str]:\n    return [l.strip() for l in text.splitlines()]\nsrc = strip_lines(source); m = strip_lines(edit.match)\nif not any(src[i:i+len(m)] == m for i in range(len(src) - len(m) + 1)):\n    raise ConfigError('match text absent from source — patch is stale')","typeGuard":"def match_exists(source: str, match: str) -> bool:\n    s = [l.strip() for l in source.splitlines()]\n    m = [l.strip() for l in match.strip().splitlines()]\n    return any(s[i:i+len(m)] == m for i in range(len(s) - len(m) + 1))","tryCatchPattern":"try:\n    patched = apply_edits(source, edits)\nexcept PatchApplicationError as e:\n    if 'not found' in str(e):\n        log.warning('stale patch skipped: %s', e)\n        patched = source\n    else:\n        raise","preventionTips":["Copy match text verbatim from the current source file","Pin the source version patches were authored against","Regenerate patch specs on every sglang upgrade","Use the diagnostic preview in the error to spot near-miss content differences"],"tags":["patching","text-matching","source-patcher","sglang"],"backgroundTag":"patch-match-not-found","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}