oraios/serena · error · FileNotFoundError
Project root not found: {project_root}
Error message
Project root not found: {project_root} What it means
Serena's ProjectConfig.autogenerate() resolves the given project_root path and raises FileNotFoundError when that directory does not exist on disk. The library refuses to auto-generate a project configuration file (.serena/project.yml) for a non-existent root, since language detection and file scanning depend on a real directory. The message includes the resolved absolute path so you can see exactly what was looked for.
Source
Thrown at src/serena/config/serena_config.py:441
"""
Autogenerate a project configuration for a given project root.
:param project_root: the path to the project root
:param serena_config: the global Serena configuration
:param project_name: the name of the project; if None, the name of the project will be the name of the directory
containing the project
:param languages: the languages of the project; if None, they will be determined automatically
:param save_to_disk: whether to save the project configuration to disk
:param interactive: whether to run in interactive CLI mode, asking the user for input where appropriate
:param asynchronous: whether to run in asynchronous mode, where time-consuming configuration parts (currently only the
determination of the list of programming languages) are determined in a background thread and initialised as empty
:return: the project configuration
"""
if interactive and asynchronous:
raise ValueError("Cannot use interactive mode with asynchronous auto-generation")
project_root = Path(project_root).resolve()
if not project_root.exists():
raise FileNotFoundError(f"Project root not found: {project_root}")
with LogTime("Project configuration auto-generation", logger=log):
log.info("Project root: %s", project_root)
project_folder_name = project_root.name
project_name = project_name or project_folder_name
use_asynchronous_language_determination = False
if languages is None:
if asynchronous:
use_asynchronous_language_determination = True
languages_to_use = [] # temporarily empty, will be determined in background thread
else:
determined_languages = cls._determine_project_language_servers(
str(project_root), interactive=interactive, serena_config=serena_config
)
languages_to_use = [l.value for l in determined_languages]
else:
languages_to_use = [lang.value for lang in languages]
config_with_comments, _ = cls._load_yaml_dict(PROJECT_TEMPLATE_FILE)
config_with_comments["project_name"] = project_nameView on GitHub (pinned to 7fcbca7e62)
Solutions
- Verify the directory exists (ls the resolved path printed in the message) and fix typos in the path
- Create the directory first (mkdir -p <root>) if you intend to initialize a new project there
- Pass an absolute path or resolve relative paths against the correct working directory before calling autogenerate/load
- If the folder moved, update the path in whatever config/CLI/IDE setting references it
Example fix
// before
config = ProjectConfig.autogenerate(project_root="~/code/my-projet", interactive=False)
// after
root = Path("~/code/my-project").expanduser().resolve()
assert root.exists(), f"missing project root: {root}"
config = ProjectConfig.autogenerate(project_root=str(root), interactive=False) Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
root = Path(project_root).expanduser().resolve()
if not root.is_dir():
raise SystemExit(f"Project root does not exist: {root}. Create it or fix the path before calling autogenerate.") Type guard
def project_root_exists(path: str | Path) -> bool:
p = Path(path).expanduser().resolve()
return p.exists() and p.is_dir() Try / catch
try:
config = ProjectConfig.autogenerate(project_root=str(root), interactive=False)
except FileNotFoundError as e:
logger.error("Project root missing: %s — create it with mkdir -p or correct the path", e)
raise Prevention
- Always pass an absolute, expanduser()-resolved path to autogenerate/load
- assert Path(root).exists() before configuring Serena in scripts
- Create the project directory (mkdir -p) before initializing Serena config for a new project
- Beware CWD differences between IDE and CLI — anchor relative paths to a known base
When it happens
Trigger: Calling ProjectConfig.autogenerate(project_root=...) (directly or via ProjectConfig.load or _create_project) with a path that does not exist after Path(project_root).resolve() — e.g. a typo, a deleted/moved directory, or a relative path resolved against the wrong working directory. Also triggered by tests test_autogenerate_empty_directory and friends when the fixture root is absent.
Common situations: Passing a path relative to a different CWD than expected (IDE vs CLI), a project folder that was renamed or removed, a typo like './my-projet', or constructing the path from an env var that is unset. Also common when creating a brand-new project: users point autogenerate at a folder they intend to create rather than one that exists.
Related errors
- Context file not found: {path.resolve()}
- Cannot use both fixed_tools and excluded_tools/included_opti
- Unknown language backend '{backend_str}': valid values are {
- Invalid line_ending: {value!r}. Valid values are: {valid}
- Cannot use interactive mode with asynchronous auto-generatio
AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29).
Data as JSON: /api/errors/2a5f03b174198e72.
Report an issue: GitHub.