oraios/serena · error · FileNotFoundError
Relative path {relative_path} does not exist.
Error message
Relative path {relative_path} does not exist. What it means
Raised by Project._create_file_collection (src/serena/project.py:400) when the local project-relative path passed to file collection (e.g. from search_project_files_for_pattern) does not exist under the project root. It guards creation of FileCollection objects over nonexistent local paths.
Source
Thrown at src/serena/project.py:400
return rel_file_paths
def _create_file_collection(self, relative_path: str, *, code_files_only: bool, skip_ignored_files: bool) -> FileCollection:
"""
Creates the file collection for the given relative path.
:param relative_path: the relative path to create the file collection for, relative to the project root
:param code_files_only: whether to include only (non-ignored) code files
:param skip_ignored_files: whether to skip ignored files; has no effect if `code_files_only` is True
:return:
"""
if FileProxy.is_external_path(relative_path):
# single external path: create appropriate proxy
file_collection = FileCollection([FileProxy.from_project_relative_path(self, relative_path)])
else:
# path is a local project path
abs_path = os.path.join(self.project_root, relative_path)
if not os.path.exists(abs_path):
raise FileNotFoundError(f"Relative path {relative_path} does not exist.")
if code_files_only:
relative_file_paths = self.gather_source_files(relative_path=relative_path)
file_collection = FileCollection.from_local_project_paths(relative_file_paths, self)
else:
abs_path = os.path.join(self.project_root, relative_path)
if os.path.isfile(abs_path):
rel_paths_to_search = [relative_path]
else:
is_ignored_path_fn = self.get_is_ignored_path_fn(base_path=relative_path, skip_ignored_paths=skip_ignored_files)
_dirs, rel_paths_to_search = scan_directory(
path=abs_path,
recursive=True,
is_ignored_dir=is_ignored_path_fn,
is_ignored_file=is_ignored_path_fn,
relative_to=self.project_root,
)
file_collection = FileCollection.from_local_project_paths(rel_paths_to_search, self)View on GitHub (pinned to 7fcbca7e62)
Solutions
- Confirm the path exists under the project root before searching
- Use a valid directory or '' for the whole project as the search scope
- Re-run after the workspace settles if files are being concurrently modified
Example fix
// before
results = project.search_project_files_for_pattern('TODO', relative_path='src/removed')
// after
scope = 'src/removed' if os.path.exists(os.path.join(project.project_root, 'src/removed')) else ''
results = project.search_project_files_for_pattern('TODO', relative_path=scope) Defensive patterns
Strategy: validation
Validate before calling
scope = relative_path or ''
if scope and not os.path.exists(os.path.join(project.project_root, scope)):
scope = '' Try / catch
try:
results = project.search_project_files_for_pattern(pattern, relative_path=relative_path)
except FileNotFoundError:
results = project.search_project_files_for_pattern(pattern) Prevention
- Verify search scope paths exist before searching
- Avoid searching while the tree is being mutated
- Default to the project root when a subpath may not exist
When it happens
Trigger: Calling search_project_files_for_pattern with a path not on disk; race between listing and opening files that were deleted concurrently.
Common situations: Searching a stale subdirectory path after a rename; searching while a build/checkout mutates the tree; typos in the search path argument.
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
- Context file not found: {path.resolve()}
- Project configuration file not found: {yaml_path}
- Serena configuration file not found: {config_file_path}
- Error: Path does not exist: {project_root}
- Error: Path is not a directory: {project_root}
AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29).
Data as JSON: /api/errors/ef089b432c4404af.
Report an issue: GitHub.