oraios/serena · error · ValueError
No occurrences of the pattern were found - NO changes were a
Error message
No occurrences of the pattern were found - NO changes were applied. Check the mode (a literal needle containing regex metacharacters must use mode 'literal'; wildcards require mode 'regex') and the path/glob restrictions, or locate the content with search_for_pattern first.
What it means
In blind-apply mode (no occurrence_ids), if the pattern matched zero occurrences, apply() raises this ValueError so no silent no-op occurs. The message points at the two most common root causes: wrong matching mode (literal vs regex) and overly restrictive path/glob scoping.
Source
Thrown at src/serena/tools/file_tools.py:297
if dry_run:
return self._render_listing(replacer, occurrences, contents, max_answer_chars, dry_run=True)
if occurrence_ids is not None:
selected, problems = self._resolve_occurrence_ids(occurrence_ids, occurrences)
if problems:
problem_lines = "\n".join(f" {p}" for p in problems)
raise ValueError(
f"{len(problems)} of the given occurrence_ids could not be resolved - NO changes were applied:\n"
f"{problem_lines}\n"
"Re-run with dry_run=True to obtain current occurrence ids."
)
if not selected:
raise ValueError("occurrence_ids is empty - pass at least one id from a dry run, or omit the parameter to replace all.")
return self._apply_occurrences(replacer, selected, contents, needle, repl)
# blind apply (no ids)
if not occurrences:
raise ValueError(
"No occurrences of the pattern were found - NO changes were applied. "
"Check the mode (a literal needle containing regex metacharacters must use mode 'literal'; "
"wildcards require mode 'regex') and the path/glob restrictions, "
"or locate the content with search_for_pattern first."
)
if expected_count >= 0 and len(occurrences) != expected_count:
listing = self._render_listing(replacer, occurrences, contents, max_answer_chars, dry_run=False)
raise ValueError(
f"expected_count={expected_count}, but the pattern matches {len(occurrences)} occurrence(s) - "
f"NO changes were applied. Review the prospective changes below; re-issue with the corrected "
f"expectation, a refined pattern, or occurrence_ids selecting the intended subset.\n{listing}"
)
ambiguous = [o for o in occurrences if o.is_ambiguous]
if ambiguous:
listing = self._render_listing(replacer, occurrences, contents, max_answer_chars, dry_run=False)
raise ValueError(
f"{len(ambiguous)} occurrence(s) are ambiguous (the pattern matches again inside the matched text, "
f"indicating possible over-matching) - NO changes were applied. Review the prospective changes below "View on GitHub (pinned to 7fcbca7e62)
Solutions
- Set mode='literal' if the needle contains regex metacharacters and should match verbatim
- Switch to mode='regex' (and escape as needed) when using wildcards like foo.*bar
- Run search_for_pattern first to confirm the text exists and under which paths
- Check the path/glob parameters are not excluding the target files
Example fix
// before agent.replace_content(needle="price(1)", repl="price(2)") // after agent.replace_content(needle="price(1)", repl="price(2)", mode="literal")
Defensive patterns
Strategy: validation
Validate before calling
found = agent.search_for_pattern(needle, path=path)
if not found:
raise LookupError(f"pattern not found: {needle!r}")
agent.replace_content(needle, repl, mode="literal" if any(c in needle for c in "()[]{}.*+?^$|\\") else "regex") Type guard
def needs_literal(needle: str) -> bool:
import re
return any(ch in needle for ch in "()[]{}.*+?^$|\\") Try / catch
try:
agent.replace_content(needle, repl)
except ValueError as e:
if "No occurrences" in str(e):
agent.replace_content(needle, repl, mode="literal")
else:
raise Prevention
- search_for_pattern before replacing to confirm existence and scope
- Default to mode='literal' for needles containing regex metacharacters
- Check path/glob restrictions when matches are unexpectedly empty
When it happens
Trigger: Using mode='regex' (default) with a literal needle containing regex metacharacters like (, [, ., or *; using wildcards while in literal mode; a path/glob filter excluding the file that contains the text; the text simply not existing (already replaced or typo).
Common situations: Replacing strings like "foo(1)" or "a.b" without mode='literal'; IDE/agent already applied the same replacement in a previous run; case or whitespace mismatch between needle and file content.
Related errors
- {len(ambiguous)} occurrence(s) are ambiguous (the pattern ma
- {len(problems)} of the given occurrence_ids could not be res
- occurrence_ids is empty - pass at least one id from a dry ru
- expected_count={expected_count}, but the pattern matches {le
- The content of {path} changed while replacing (occurrence {e
AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29).
Data as JSON: /api/errors/3e2ede1e7e02834a.
Report an issue: GitHub.