oraios/serena · error · FileNotFoundError

Project root not found: {project_root}

Error message

Project root not found: {project_root}

What it means

Raised by Project.load in src/serena/project.py:146 when the resolved project root path does not exist on disk. The loader resolves the path via Path.resolve() and bails out before attempting to load or auto-generate the project configuration.

Source

Thrown at src/serena/project.py:146

        # The backend configuration is fundamentally owned by the agent, so it takes
        # precedence. (Note: The agent does not necessary honour the project's choice,
        # as it may be invalid.)
        if self._agent is not None:
            return self._agent.get_language_backend()
        else:
            return self.serena_config.determine_language_backend(self.project_config)

    @classmethod
    def load(
        cls,
        project_root: str | Path,
        serena_config: "SerenaConfig",
        autogen: ProjectConfigAutoGenerationMode = ProjectConfigAutoGenerationMode.SYNCHRONOUS,
    ) -> "Project":
        assert serena_config is not None
        project_root = Path(project_root).resolve()
        if not project_root.exists():
            raise FileNotFoundError(f"Project root not found: {project_root}")
        project_config = ProjectConfig.load(project_root, serena_config=serena_config, autogen=autogen)
        return Project(project_root=str(project_root), project_config=project_config, serena_config=serena_config)

    def save_config(self) -> None:
        """
        Saves the current project configuration to disk.
        """
        self.project_config.save(self.path_to_project_yml())

    def path_to_serena_data_folder(self) -> str:
        return self._serena_data_folder

    def path_to_project_yml(self) -> str:
        return self.serena_config.get_project_yml_location(self.project_root)

    def is_trusted(self) -> bool:
        """
        Checks whether the project is trusted, based on the global configuration.

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Verify the directory exists: os.path.isdir('/abs/path/to/project') before calling load
  2. Pass an absolute, resolved path (Path(path).resolve()) instead of a relative one
  3. Fix or update the path stored in whatever config/script supplies project_root

Example fix

// before
project = Project.load('~/projects/myrepo', serena_config=cfg)  # may not exist / not expanded
// after
root = Path('~/projects/myrepo').expanduser().resolve()
assert root.exists(), f'Missing project root: {root}'
project = Project.load(str(root), serena_config=cfg)
Defensive patterns

Strategy: validation

Validate before calling

root = Path(project_root).expanduser().resolve()
if not root.is_dir():
    raise NotADirectoryError(f'Project root missing: {root}')

Try / catch

try:
    project = Project.load(project_root, serena_config=cfg)
except FileNotFoundError as e:
    logging.error('Bad project root: %s', e)
    raise

Prevention

When it happens

Trigger: Calling Project.load with a project_root that is misspelled, was deleted or moved, or is a relative path resolved against an unexpected working directory.

Common situations: Passing a path from stale config after a checkout was renamed; mounting the repository at a different location in CI; relative paths resolved against a different CWD in tools/agents.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29). Data as JSON: /api/errors/4a1da91ae3f3553f. Report an issue: GitHub.