affaan-m/ECC · error · ValueError

artifact must be a resident regular file

Error message

artifact must be a resident regular file

What it means

After lstat-ing the target without following symlinks, `_read_local` verifies it is a regular file and that no sticky pinned/immutable-style flag (`0x40000000`, checked via `st_flags`) is set. Anything else — a directory, FIFO, device node, socket, symlink, or a file with the offending flag — is rejected so the reader only consumes ordinary resident regular files that the identity-based TOCTOU checks can reason about.

Solutions

  1. Ensure the path names a real regular file: `Path(p).is_file()` (after resolving symlinks) before calling.
  2. Replace symlinks with hard copies of the artifact, or resolve the symlink and pass the final target path (which must still be absolute and canonical).
  3. Inspect the file's flags (`ls -lO` on macOS/BSD) and clear the pinned/immutable bit (`chflags nouchg <file>`) if it was set by another tool.
  4. Regenerate the artifact if it was produced as a special file (pipe/device) instead of a regular file on disk.

Example fix

// before
artifact_path = "/out/latest"  # actually a symlink chain ending in a directory
// after
import os, stat
info = os.lstat(artifact_path)
assert stat.S_ISREG(info.st_mode) and not (getattr(info, 'st_flags', 0) & 0x40000000)
artifact_path = os.path.realpath(artifact_path)
Defensive patterns

Strategy: validation

Validate before calling

import os, stat
def assert_readable_regular_file(path: str) -> None:
    info = os.stat(path, follow_symlinks=False)
    if not stat.S_ISREG(info.st_mode):
        raise ValueError(f"not a regular file: {path}")
    if getattr(info, "st_flags", 0) & 0x40000000:
        raise ValueError(f"file has pinned/immutable flag set: {path}")

Type guard

def is_plain_regular_file(path: str) -> bool:
    import os, stat
    try:
        info = os.stat(path, follow_symlinks=False)
    except OSError:
        return False
    return stat.S_ISREG(info.st_mode) and not (getattr(info, "st_flags", 0) & 0x40000000)

Try / catch

try:
    req = load_application_request(p)
except ValueError as e:
    if str(e) == "artifact must be a resident regular file":
        target = os.path.realpath(p)
        clear_pinned_flags(target)          # e.g. chflags nouchg on macOS/BSD
        req = load_application_request(target)
    else:
        raise

Prevention

When it happens

Trigger: Pointing `_artifact` or `load_application_request` at a directory, a symlink, a named pipe, `/dev/null`, or a file whose `st_flags` include bit `0x40000000` (e.g. certain pinned/immutable marker flags on BSD/macOS filesystems).

Common situations: A typo where the path points at the output directory instead of the file inside it; a stale symlink left by a previous build; creating artifacts via `mkfifo` for streaming; filesystem-specific flag setting from backup or dedup tools.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/9ebeac434b5533a1. Report an issue: GitHub.

Appendix: source

Thrown at skills/taste-application/scripts/tasteforge/integration.py:123

            parent = child
        return parent
    except BaseException:
        os.close(parent)
        raise


def _read_local(raw: str, *, parse_json: bool, expected_size: int | None = None,
                expected_hash: str | None = None) -> Any:
    path = Path(raw)
    if not path.is_absolute() or str(path) != raw or ".." in path.parts:
        raise ValueError("artifact path must be canonical and absolute")
    parent = descriptor = None
    try:
        flags = os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK
        parent = _parent_fd(path)
        before = os.stat(path.name, dir_fd=parent, follow_symlinks=False)
        if not stat.S_ISREG(before.st_mode) or getattr(before, "st_flags", 0) & 0x40000000:
            raise ValueError("artifact must be a resident regular file")
        if expected_size is None:
            expected_size = before.st_size
        if parse_json and expected_size > _MAX_JSON:
            raise ValueError("JSON artifact exceeds local size limit")
        if before.st_size != expected_size:
            raise ValueError("artifact byte count mismatch")
        descriptor = os.open(path.name, flags, dir_fd=parent)
        if _identity(before) != _identity(os.fstat(descriptor)):
            raise ValueError("artifact changed before reading")
        digest, chunks, count = hashlib.sha256(), [], 0
        while data := os.read(descriptor, 65536):
            count += len(data)
            if count > expected_size:
                raise ValueError("artifact byte count exceeded during reading")
            digest.update(data)
            if parse_json:
                chunks.append(data)
        # Rewalk the named path: a pinned old directory fd can outlive a rename.

View on GitHub (pinned to 8321021c54)