{"record":{"id":"6a82038fd7db0a97","repo":"oraios/serena","slug":"pass-either-content-or-source-file-path","errorCode":null,"errorMessage":"Pass either content or source_file_path","messagePattern":"Pass either content or source_file_path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/serena/util/text_utils.py","lineNumber":145,"sourceCode":"    \"\"\"\n    Search for a pattern in text content. Supports both regex and glob-like patterns.\n\n    :param pattern: Pattern to search for (regex or glob-like pattern)\n    :param content: The text content to search. May be None if source_file_path is provided.\n    :param source_file_path: Optional path to the source file. If content is None,\n        this has to be passed and the file will be read.\n    :param context_lines_before: Number of context lines to include before matches\n    :param context_lines_after: Number of context lines to include after matches\n    :param multiline: whether to apply multi-line matching, enabling the flags re.DOTALL and re.MULTILINE\n    :return: List of `TextSearchMatch` objects\n    :raises: ValueError if the pattern is not valid\n    \"\"\"\n    if source_file_path and content is None:\n        with open(source_file_path) as f:\n            content = f.read()\n\n    if content is None:\n        raise ValueError(\"Pass either content or source_file_path\")\n\n    matches = []\n    lines = TextUtils.split_lines(content)\n    total_lines = len(lines)\n\n    # For multiline matches, optionally use DOTALL so '.' matches newlines\n    flags = (re.MULTILINE | re.DOTALL) if multiline else 0\n    compiled_pattern = re.compile(pattern, flags)\n    # Search across the entire content as a single string\n    for match in compiled_pattern.finditer(content):\n        start_pos = match.start()\n        end_pos = match.end()\n\n        # Find the line numbers for the start and end positions\n        start_line_num = TextUtils.get_line_from_index(content, start_pos)\n        end_line_num = TextUtils.get_line_from_index(content, end_pos)\n        if end_line_num > start_line_num and TextUtils.get_line_col_from_index(content, end_pos)[1] == 0:\n            # `end_pos` is exclusive, so if it is at the start of a line, the match ends with the","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/util/text_utils.py#L127-L163","documentation":"TextUtils.search_text requires the text to search: it accepts either raw content or a source_file_path it reads itself. If both are absent (content is None after optional file read) it raises ValueError, since searching an empty input would silently return no matches.","triggerScenarios":"Calling search_text(pattern) with neither content nor source_file_path, or with source_file_path set but content explicitly None and the path handling skipped — e.g. search_text(pattern, content=None, source_file_path=None).","commonSituations":"Programmatic callers passing variables that are None because a previous read failed; refactors changing the function signature; tests forgetting required arguments.","solutions":["Pass source_file_path pointing to an existing file","Or read the file yourself and pass content=<string>","Validate inputs before the call and raise a clearer domain-specific error","Fix callers that pass None after a failed file read"],"exampleFix":"// before\nTextUtils.search_text('pattern')  # ValueError\n// after\nTextUtils.search_text('pattern', source_file_path='src/main.py')\n# or\ncontent = open('src/main.py').read()\nTextUtils.search_text('pattern', content=content)","handlingStrategy":"validation","validationCode":"def safe_search(pattern: str, path: str | None = None, content: str | None = None):\n    if content is None and path is None:\n        raise ValueError(\"search_text needs content or source_file_path\")\n    return TextUtils.search_text(pattern, source_file_path=path, content=content)","typeGuard":null,"tryCatchPattern":"try:\n    matches = TextUtils.search_text(pattern, source_file_path=path)\nexcept ValueError as e:\n    log.error(\"search_text misused: %s\", e)","preventionTips":["Always pass either content or source_file_path explicitly","Check that the source file exists before passing its path","Wrap search helpers so None inputs fail fast with a clear message"],"tags":["python","text-search","valueerror","argument-validation"],"backgroundTag":"missing-required-argument","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}