oraios/serena · error · ValueError
Invalid language server: '{orig_language_str}'.\nValid value
Error message
Invalid language server: '{orig_language_str}'.\nValid values are: {[l.value for l in LanguageServerId]} What it means
When parsing a Serena project config dict, _from_dict maps each entry of the 'language' list through LanguageServerId(ls_str). If the string is not a valid enum value (and is not resolved by the lang_name_mapping alias table), LanguageServerId(...) raises ValueError, which is re-raised with a message listing all valid values. This validates the 'language' field of .serena/project.yml before a language server is ever started.
Source
Thrown at src/serena/config/serena_config.py:593
Create a ProjectConfig instance from a (full) configuration dictionary
:param data: the configuration dictionary; must contain all required fields and use the same field names as
the ProjectConfig dataclass
:param local_override_keys: the list of keys that have been overridden from project.local.yml
"""
# map languages to list of enum items, checking for errors
lang_name_mapping = {"javascript": "typescript"}
ls_ids: list[LanguageServerId] = []
for ls_str in data["language_servers"]:
orig_language_str = ls_str
try:
ls_str = ls_str.lower()
if ls_str in lang_name_mapping:
ls_str = lang_name_mapping[ls_str]
ls_id = LanguageServerId(ls_str)
ls_ids.append(ls_id)
except ValueError as e:
raise ValueError(
f"Invalid language server: '{orig_language_str}'.\nValid values are: {[l.value for l in LanguageServerId]}"
) from e
# Validate activation_command_timeout
activation_command_timeout_raw = data.get("activation_command_timeout", 180.0)
try:
activation_command_timeout = float(activation_command_timeout_raw)
except (TypeError, ValueError) as e:
raise ValueError(f"activation_command_timeout must be a number, got: {activation_command_timeout_raw}") from e
if activation_command_timeout <= 0:
raise ValueError(f"activation_command_timeout must be positive, got: {activation_command_timeout}")
# Validate symbol_info_budget
symbol_info_budget_raw = data["symbol_info_budget"]
symbol_info_budget = symbol_info_budget_raw
if symbol_info_budget is not None:
try:
symbol_info_budget = float(symbol_info_budget_raw)View on GitHub (pinned to 7fcbca7e62)
Solutions
- Read the valid values listed in the error message and replace the language string with an exact match, e.g. languages=['python','typescript']
- Check LanguageServerId enum values (src/serena/config/serena_config.py) for the canonical spelling of your language
- Run serena with --log-level debug or inspect lang_name_mapping to see supported aliases, or use an alias like 'py' if mapped
- Upgrade/downgrade Serena if the language value existed in another version
Example fix
// before config = ProjectConfig.autogenerate(project_root=root, languages=["ts", "py"]) // after config = ProjectConfig.autogenerate(project_root=root, languages=["typescript", "python"])
Defensive patterns
Strategy: validation
Validate before calling
from serena.config.serena_config import LanguageServerId
valid = {l.value for l in LanguageServerId}
bad = [lang for lang in languages if lang.lower() not in valid]
if bad:
raise ValueError(f"Invalid languages {bad}; valid values: {sorted(valid)}") Type guard
def is_valid_language(lang: str) -> bool:
from serena.config.serena_config import LanguageServerId
return lang.lower() in {l.value for l in LanguageServerId} Try / catch
try:
config = ProjectConfig.autogenerate(project_root=root, languages=languages)
except ValueError as e:
if 'Invalid language server' in str(e):
logger.error("Fix the 'language' entries in project.yml. %s", e)
raise Prevention
- Copy language names exactly from the LanguageServerId enum values listed in the error message
- Use lowercase canonical names like 'python', 'typescript', 'go' in project.yml
- After upgrading Serena, diff your project.yml languages against the new enum
- Prefer letting autogenerate detect languages instead of hand-writing them
When it happens
Trigger: Calling ProjectConfig.autogenerate(..., languages=[...]) or ProjectConfig.load() on a project.yml whose 'language' entries contain a misspelled or unsupported language string (e.g. 'typescriptreact', 'py', 'js' if not aliased, or wrong case handled only for known aliases). Directly invoked by tests test_language_backend_parsed_from_dict etc.
Common situations: Hand-editing project.yml and writing 'python3' or 'typescript-react' instead of the enum value; copying config from another tool that uses different language names; a Serena version change where a language value was renamed or added; typos like 'pyton'.
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
- Unknown language backend '{backend_str}': valid values are {
- Invalid line_ending: {value!r}. Valid values are: {valid}
- Cannot use both fixed_tools and excluded_tools/included_opti
- activation_command_timeout must be a number, got: {activatio
- activation_command_timeout must be positive, got: {activatio
AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29).
Data as JSON: /api/errors/3846bf54990f9139.
Report an issue: GitHub.