oraios/serena · error · SerenaConfigError
Unknown placeholder '${name}' in project_serena_folder_locat
Error message
Unknown placeholder '${name}' in project_serena_folder_location. Supported placeholders: {', '.join('$' + k for k in placeholders)} What it means
Serena expands `$placeholder` tokens in the `project_serena_folder_location` config template using a fixed placeholder map. If the template contains a `$NAME` that is not a key of that map, the `_replace` callback inside `re.sub` raises SerenaConfigError. This fails fast so a mis-typed template variable is caught at config-processing time instead of silently expanding to an empty string.
Source
Thrown at src/serena/config/serena_config.py:1368
save_yaml(self.config_file_path, commented_yaml)
@staticmethod
def _resolve_serena_folder_location(template: str, placeholders: dict[str, str]) -> str:
"""
Resolves a folder location template by replacing known ``$placeholder`` tokens
and raising on any unrecognised ones.
:param template: the template string (e.g. ``"$projectDir/.serena"``)
:param placeholders: mapping from placeholder name (without ``$``) to replacement value
:return: the resolved absolute path
:raises SerenaConfigError: if the template contains an unknown ``$placeholder``
"""
def _replace(match: re.Match[str]) -> str:
name = match.group(1)
if name not in placeholders:
raise SerenaConfigError(
f"Unknown placeholder '${name}' in project_serena_folder_location. "
f"Supported placeholders: {', '.join('$' + k for k in placeholders)}"
)
return placeholders[name]
result = re.sub(r"\$([A-Za-z_]\w*)", _replace, template)
return os.path.abspath(result)
def get_configured_project_serena_folder(self, project_root: str | Path) -> str:
"""
Returns the resolved absolute path to the .serena data folder for a project,
applying placeholder substitution to ``project_serena_folder_location``
without any fallback logic.
:param project_root: the absolute path to the project root directory
:return: the resolved absolute path to the project's .serena folder
:raises SerenaConfigError: if the template contains an unknown placeholder
"""View on GitHub (pinned to 7fcbca7e62)
Solutions
- Replace the unknown `$NAME` with a supported placeholder listed in the error message (they are echoed verbatim).
- If you meant a literal `$`, escape or remove it — the regex matches any `$` followed by a letter/underscore, so `$100` is safe but `$usd` is not.
- Check serena_config.yml for shell-variable leftovers and remove them.
- Update the placeholder map at the call site if a new placeholder is genuinely required (library change, not a config fix).
Example fix
# before (serena_config.yml) project_serena_folder_location: "$HOMEPROJ/.serena/projects" # after project_serena_folder_location: "$project_root/.serena/projects"
Defensive patterns
Strategy: validation
Validate before calling
import re
def validate_placeholders(template: str, placeholders: dict[str, str]) -> list[str]:
return [n for n in re.findall(r"\$([A-Za-z_]\w*)", template) if n not in placeholders] Type guard
def is_valid_template(template: str, placeholders: dict[str, str]) -> bool:
return not validate_placeholders(template, placeholders) Try / catch
try:
path = config.expand_project_serena_folder_location()
except SerenaConfigError as e:
logger.error("Fix project_serena_folder_location: %s", e)
raise Prevention
- List supported placeholders (they are printed in the error) before writing the template.
- Avoid literal `$` followed by letters in config values unless intended as a placeholder.
- Validate the config template in CI before deploying.
- Copy placeholder names from official docs instead of shell variable conventions.
When it happens
Trigger: Setting `project_serena_folder_location` in serena_config.yml to a value containing a `$`-prefixed token whose name is not in the placeholders dict (e.g. a typo like `$HOMEPROJECT` or a literal `$` followed by letters such as a shell variable or price string `$100usd`). Any code path that resolves this template calls `re.sub(r"\$([A-Za-z_]\w*)", _replace, template)` and raises on the first unknown name.
Common situations: Users copying shell-style variable syntax (`$PROJECT`) that the template doesn't support, typos in supported placeholder names, or pasting paths containing `$` + letters (e.g. macOS/brew paths or currency strings) into the config value.
Related errors
- Session ID is required in the hook input data
- Tool name is required in the hook input data
- This method must be overridden for each subclass
- Context file not found: {path.resolve()}
- 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/cad7ec8aec9bc202.
Report an issue: GitHub.