oraios/serena · error
Invalid mode: '{self.mode}', expected 'literal' or 'regex'.
Error message
Invalid mode: '{self.mode}', expected 'literal' or 'regex'. What it means
Thrown by the replace() method (and RegExpEditMode construction) when the mode attribute is neither 'literal' nor 'regex'. Serena only supports these two modes for how the needle is interpreted, and it validates strictly rather than guessing.
Source
Thrown at src/serena/util/text_utils.py:463
repl: str,
) -> str:
"""
Performs the replacement.
Raises ValueError if no match is found, or if multiple matches are found while allow_multiple_occurrences is False.
:param content: the content in which to perform the replacement
:param needle: the search expression, which is either a literal string or a regular expression, depending on the mode
:param repl: the replacement string, which, in regex mode, may contain backreferences in the form of $!1, $!2, etc. to
refer to matched groups in the search expression
:return: the updated content after performing the replacement
"""
if self.mode == "literal":
regex = re.escape(needle)
elif self.mode == "regex":
regex = needle
else:
raise ValueError(f"Invalid mode: '{self.mode}', expected 'literal' or 'regex'.")
regex_flags = (re.MULTILINE | re.DOTALL) if self.regex_multiline else 0
# create replacement function with validation and backreference handling
repl_fn = self._create_replacement_function(regex, repl, regex_flags=regex_flags)
# perform replacement
updated_content, n = re.subn(regex, repl_fn, content, flags=regex_flags)
if n == 0:
raise ValueError("Error: No matches of search expression found.")
if not self.allow_multiple_occurrences and n > 1:
raise ValueError(
f"Expression matches {n} occurrences. "
"Please revise the expression to be more specific or enable allow_multiple_occurrences if this is expected."
)
return updated_content
View on GitHub (pinned to 7fcbca7e62)
Solutions
- Set mode to exactly 'literal' or 'regex' (lowercase)
- Strip and normalize any user-supplied mode string before constructing the edit
- Add a pre-construction validation that rejects unknown modes with a clearer message
Example fix
// before
TextReplacement(mode='Literal', needle='foo', repl='bar')
// after
mode = user_mode.strip().lower()
assert mode in ('literal', 'regex')
TextReplacement(mode=mode, needle='foo', repl='bar') Defensive patterns
Strategy: validation
Validate before calling
if mode not in ('literal', 'regex'):
raise ValueError(f'mode must be literal or regex, got {mode!r}') Type guard
def is_valid_mode(mode: object) -> TypeGuard[Literal['literal','regex']]:
return mode in ('literal', 'regex') Try / catch
try:
editor.replace(content, needle, repl)
except ValueError as e:
if 'Invalid mode' in str(e):
editor.mode = 'literal'
updated = editor.replace(content, needle, repl)
else:
raise Prevention
- Use Literal['literal','regex'] type annotations
- Normalize user/config-supplied mode with .strip().lower()
- Centralize mode selection in one enum-like constant set
When it happens
Trigger: Passing a mode string with different casing ('Literal'), a typo ('regex ' with trailing space, 'regexpr'), or a None/other value in an object using this text-editing utility.
Common situations: Config files or templates where the mode is read from user input or YAML/JSON and not validated; refactors that renamed mode constants.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid mode: '{mode}', expected 'literal' or 'regex'.
- Unknown language '{lang}'. Supported: {all_langs}
- Cannot edit external file: {relative_path}
- Cannot insert after this symbol (not a function, class or me
- Cannot use both fixed_tools and excluded_tools/included_opti
AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29).
Data as JSON: /api/errors/4f06e7b6eaa663e2.
Report an issue: GitHub.