{"record":{"id":"831ff07477c5e9c8","repo":"oraios/serena","slug":"match-must-be-unique-found-len-matches-matches","errorCode":null,"errorMessage":"Match must be unique; found {len(matches)} matches for regex: {regex}","messagePattern":"Match must be unique; found (.+?) matches for regex: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/serena/util/text_utils.py","lineNumber":670,"sourceCode":"    \"\"\"\n    Finds the line and column number of the first match of a regex pattern in the given content.\n\n    :param content: the text content to search through\n    :param regex: the regular expression pattern to search for; it must match part of a single line,\n        and contain exactly one group that captures the position of interest (e.g., the exact variable name to find the coordinates of)\n    :param require_unique: if True, raises an error if not exactly one match is found;\n        if False, returns None if no match is found, and returns the coordinates of the first match if multiple matches are found\n    :return: the coordinates of the match or None\n    \"\"\"\n    pattern = re.compile(regex, flags=re.MULTILINE | re.DOTALL)\n    matches = list(pattern.finditer(content))\n    if len(matches) == 0:\n        if require_unique:\n            raise ValueError(f\"No match found for regex: {regex}\")\n        return None\n    else:\n        if require_unique and len(matches) > 1:\n            raise ValueError(f\"Match must be unique; found {len(matches)} matches for regex: {regex}\")\n        match = matches[0]\n        if len(match.groups()) != 1:\n            raise ValueError(f\"Regex must contain exactly one group to capture the position, but found {len(match.groups())} groups.\")\n        index_in_content = match.start(1)\n        line, col = TextUtils.get_line_col_from_index(content, index_in_content)\n        return TextCoords(line, col)\n","sourceCodeStart":652,"sourceCodeEnd":677,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/util/text_utils.py#L652-L677","documentation":"find_text_coordinates() with require_unique=True demands exactly one match so the returned coordinates are unambiguous. When the regex matches multiple times it cannot know which occurrence's position to return, so it raises listing the match count.","triggerScenarios":"Calling find_text_coordinates with require_unique=True on a regex that matches 2+ locations, e.g. a generic method-name pattern that appears in several components.","commonSituations":"Repeated helper names across templates; same attribute like (click)=\"save()\" in multiple places; overly broad patterns lacking component/section context.","solutions":["Add unique context before/after the capture (enclosing component, class, or block)","Narrow the searched content region to the relevant section before locating","If any occurrence is acceptable, pass require_unique=False (first match is used)"],"exampleFix":"// before\nfind_text_coordinates(content, r'(save\\(\\))')  # matches in 3 components\n// after\nfind_text_coordinates(content, r'component \"header\"[\\s\\S]*?(save\\(\\))')  # scoped to one block","handlingStrategy":"validation","validationCode":"hits = re.findall(regex, content, flags=re.MULTILINE|re.DOTALL)\nif len(hits) > 1:\n    raise ValueError('locator matches multiple sites; add context or use require_unique=False')","typeGuard":null,"tryCatchPattern":"try:\n    coords = find_text_coordinates(content, regex)\nexcept ValueError as e:\n    if 'Match must be unique' in str(e):\n        coords = find_text_coordinates(content, regex, require_unique=False)\n    else:\n        raise","preventionTips":["Anchor locators to unique enclosing structures","Narrow the content slice searched before locating","Use require_unique=False only when first-match semantics are fine"],"tags":["regex","text-processing","multiple-matches"],"backgroundTag":"ambiguous-regex-match","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}