oraios/serena · error · FileNotFoundError
File read '{file_path}' failed: File does not exist.
Error message
File read '{file_path}' failed: File does not exist. What it means
FileNotFoundError raised by FileUtils.read_file (src/solidlsp/ls_utils.py:411) when the requested file_path does not exist on disk. The existence check happens before opening, so the message is explicit about the missing path.
Source
Thrown at src/solidlsp/ls_utils.py:411
Utility functions for file operations.
"""
ArchiveType = Literal["tar", "gztar", "bztar", "xztar", "zip", "zip.gz", "gz", "binary"]
@staticmethod
def read_file(file_path: str, encoding: str) -> str:
"""
Reads the file at the given path using the given encoding and returns the contents as a string.
If decoding fails, tries to detect the encoding using charset_normalizer.
Line endings are normalized to LF (universal newlines), irrespective of the encoding
used to decode the file.
Raises FileNotFoundError if the file does not exist.
"""
if not os.path.exists(file_path):
log.error(f"Failed to read '{file_path}': File does not exist.")
raise FileNotFoundError(f"File read '{file_path}' failed: File does not exist.")
try:
try:
with open(file_path, encoding=encoding) as inp_file:
return inp_file.read()
except UnicodeDecodeError as ude:
results = charset_normalizer.from_path(file_path)
match = results.best()
if match:
log.warning(
f"Could not decode {file_path} with encoding='{encoding}'; using best match '{match.encoding}' instead",
)
# Decoding the raw bytes bypasses the universal-newline translation that the
# open() call above applies, so normalize explicitly to keep both paths equivalent.
decoded = match.raw.decode(match.encoding)
return decoded.replace("\r\n", "\n").replace("\r", "\n")
raise ude
except Exception as exc:
log.error(f"Failed to read '{file_path}' with encoding '{encoding}': {exc}")View on GitHub (pinned to 7fcbca7e62)
Solutions
- Check os.path.exists(file_path) and print os.path.abspath to spot wrong working-directory assumptions.
- Refresh the file list / recompute the path after renames or deletions.
- Verify case matches exactly on case-sensitive filesystems.
Example fix
// before
content = FileUtils.read_file("src/Modle.py")
// after
path = "src/Model.py"
if not os.path.exists(path):
raise SkipFile(f"missing: {os.path.abspath(path)}")
content = FileUtils.read_file(path) Defensive patterns
Strategy: validation
Validate before calling
def readable(path: str) -> bool:
return os.path.isfile(path) and os.access(path, os.R_OK) Type guard
def resolve_existing(path: str) -> str | None:
return path if os.path.exists(path) else None Try / catch
try:
content = FileUtils.read_file(path)
except FileNotFoundError:
log.warning("missing file: %s", os.path.abspath(path))
content = None Prevention
- Check os.path.exists with an absolute path before reads
- Refresh cached file references after renames/deletes
- Beware case-sensitivity differences across filesystems
- Ensure generated files exist before consumers run
When it happens
Trigger: Calling read_file (or contents / request_containing_symbol which use it) with a path that was deleted, renamed, never created, or spelled with a wrong relative/absolute prefix.
Common situations: Stale file references after refactors; relative paths resolved against the wrong working directory; generated files not yet produced; case-sensitive filesystems with mismatched casing.
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
- Error: Path does not exist: {project_root}
- Error: Path is not a directory: {project_root}
- Archive not found: {self.archive_path}
- Internal mode '{from_internal}' not found in {SERENAS_OWN_MO
- Internal context '{from_internal}' not found in {SERENAS_OWN
AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29).
Data as JSON: /api/errors/b66a7bde23f18f41.
Report an issue: GitHub.