JuliusBrussee/caveman · error · FileNotFoundError

File not found: {filepath}

Error message

File not found: {filepath}

What it means

Raised by compress_file() after resolving the argument with Path.resolve(): the target file does not exist on disk. The check runs before size/sensitivity checks, so a nonexistent path always fails here first, with the resolved absolute path in the message.

Source

Thrown at skills/caveman-compress/scripts/compress.py:282

ORIGINAL (reference only):
{original}

COMPRESSED (fix this):
{compressed}

Return ONLY the fixed compressed file. No explanation.
"""


# ---------- Core Logic ----------


def compress_file(filepath: Path) -> bool:
    # Resolve and validate path
    filepath = filepath.resolve()
    MAX_FILE_SIZE = 500_000  # 500KB
    if not filepath.exists():
        raise FileNotFoundError(f"File not found: {filepath}")
    if filepath.stat().st_size > MAX_FILE_SIZE:
        raise ValueError(f"File too large to compress safely (max 500KB): {filepath}")

    # Refuse files that look like they contain secrets or PII. Compressing ships
    # the raw bytes to the Anthropic API — a third-party boundary — so we fail
    # loudly rather than silently exfiltrate credentials or keys. Override is
    # intentional: the user must rename the file if the heuristic is wrong.
    if is_sensitive_path(filepath):
        raise ValueError(
            f"Refusing to compress {filepath}: filename looks sensitive "
            "(credentials, keys, secrets, or known private paths). "
            "Compression sends file contents to the Anthropic API. "
            "Rename the file if this is a false positive."
        )

    print(f"Processing: {filepath}")

    if not should_compress(filepath):

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Check the resolved path printed in the error with ls — it is absolute, so cwd confusion is ruled out.
  2. Fix the typo or pass the correct current location of the file.
  3. If the file was expected to exist, find where it moved (git status / glob for the filename) and re-run with the new path.

Example fix

# before
compress_file(Path('docs/README-caveman.md'))  # FileNotFoundError: .../docs/README-caveman.md

# after
compress_file(Path('docs/README.md'))
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def compressible_path(raw: str) -> bool:
    p = Path(raw).resolve()
    return p.is_file() and not p.is_symlink() or p.exists()

Try / catch

try:
    compress_file(path)
except FileNotFoundError as e:
    # resolved absolute path is in the message; locate the moved file and re-run
    path = relocate(path)
    raise

Prevention

When it happens

Trigger: Invoking the compress skill or compress.py with a path that is misspelled, relative to a different cwd, already deleted/moved, or a symlink whose target is gone (resolve() surfaces the dead target).

Common situations: Agent passes a path quoted from an old conversation after the file was renamed; relative paths evaluated from a different working directory; case-sensitivity mismatches on Linux; a temp file cleaned up mid-session.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/6223e63f0c7c6d1f. Report an issue: GitHub.