{"record":{"id":"3d9c6bcc9b478bb6","repo":"oraios/serena","slug":"len-problems-of-the-given-occurrence-ids-could","errorCode":null,"errorMessage":"{len(problems)} of the given occurrence_ids could not be resolved - NO changes were applied:\n{problem_lines}\nRe-run with dry_run=True to obtain current occurrence ids.","messagePattern":"(.+?) of the given occurrence_ids could not be resolved - NO changes were applied:\n(.+?)\nRe-run with dry_run=True to obtain current occurrence ids\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/serena/tools/file_tools.py","lineNumber":286,"sourceCode":"            occurrences you expect to be replaced. If the actual count differs, nothing is changed and\n            the list of prospective changes is returned. -1 disables the guard.\n        :param max_answer_chars: if the output exceeds this many characters, a shortened version is\n            returned. -1 uses the configured default.\n        :return: in a dry run, the prospective changes; otherwise a summary of the applied replacements\n        \"\"\"\n        replacer = MultiFileContentReplacer(mode=mode)\n        files = self._collect_files(relative_path, paths_include_glob, paths_exclude_glob)\n        occurrences = replacer.find_occurrences(files, needle, repl)\n        contents = dict(files)\n\n        if dry_run:\n            return self._render_listing(replacer, occurrences, contents, max_answer_chars, dry_run=True)\n\n        if occurrence_ids is not None:\n            selected, problems = self._resolve_occurrence_ids(occurrence_ids, occurrences)\n            if problems:\n                problem_lines = \"\\n\".join(f\"  {p}\" for p in problems)\n                raise ValueError(\n                    f\"{len(problems)} of the given occurrence_ids could not be resolved - NO changes were applied:\\n\"\n                    f\"{problem_lines}\\n\"\n                    \"Re-run with dry_run=True to obtain current occurrence ids.\"\n                )\n            if not selected:\n                raise ValueError(\"occurrence_ids is empty - pass at least one id from a dry run, or omit the parameter to replace all.\")\n            return self._apply_occurrences(replacer, selected, contents, needle, repl)\n\n        # blind apply (no ids)\n        if not occurrences:\n            raise ValueError(\n                \"No occurrences of the pattern were found - NO changes were applied. \"\n                \"Check the mode (a literal needle containing regex metacharacters must use mode 'literal'; \"\n                \"wildcards require mode 'regex') and the path/glob restrictions, \"\n                \"or locate the content with search_for_pattern first.\"\n            )\n        if expected_count >= 0 and len(occurrences) != expected_count:\n            listing = self._render_listing(replacer, occurrences, contents, max_answer_chars, dry_run=False)","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/tools/file_tools.py#L268-L304","documentation":"replace_content (apply) supports selecting specific matches by occurrence_id obtained from a dry run. If any provided ids cannot be resolved against the freshly scanned occurrences, apply() raises this ValueError and deliberately applies NO changes (all-or-nothing semantics).","triggerScenarios":"Calling replace_content with occurrence_ids from an earlier dry run after the file (or other matching files) changed; passing ids from a different needle/pattern than the current call; malformed ids outside the valid range.","commonSituations":"Two-step edit workflows where an edit happened between the dry run and the apply; concurrent modification by an editor or another agent; reusing ids across multiple replace operations.","solutions":["Re-run the operation with dry_run=True to get fresh occurrence ids, then apply with the new ids","Confirm the same needle, repl, mode, path, and globs are used for the dry run and the apply call","If the intent is to replace all matches, omit occurrence_ids entirely","Check the listed problem lines to identify which ids are stale or invalid"],"exampleFix":"// before\nresult = agent.replace_content(needle=\"foo\", repl=\"bar\", occurrence_ids=[\"o1\",\"o9\"])\n// after\ndry = agent.replace_content(needle=\"foo\", repl=\"bar\", dry_run=True)\nids = [o.id for o in dry.occurrences]\nresult = agent.replace_content(needle=\"foo\", repl=\"bar\", occurrence_ids=ids)","handlingStrategy":"retry","validationCode":"dry = agent.replace_content(needle=needle, repl=repl, dry_run=True)\nvalid_ids = {o.id for o in dry.occurrences}\nassert set(occurrence_ids) <= valid_ids, \"stale occurrence ids\"","typeGuard":"def ids_fresh(ids, dry_run_result) -> bool:\n    return all(i in {o.id for o in dry_run_result.occurrences} for i in ids)","tryCatchPattern":"try:\n    agent.replace_content(needle, repl, occurrence_ids=ids)\nexcept ValueError as e:\n    if \"could not be resolved\" in str(e):\n        dry = agent.replace_content(needle, repl, dry_run=True)\n        agent.replace_content(needle, repl, occurrence_ids=[o.id for o in dry.occurrences])\n    else:\n        raise","preventionTips":["Always generate occurrence ids immediately before applying","Use identical needle/repl/mode/path parameters for dry run and apply","Never cache occurrence ids across edits"],"tags":["stale-state","validation","replace"],"backgroundTag":"stale-occurrence-id","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}