affaan-m/ECC · error · ContractError
receipt source is not a regular file
Error message
receipt source is not a regular file: {path} What it means
_sha256 opened the receipt path with O_NOFOLLOW successfully, but fstat shows the opened file is not a regular file (e.g. a FIFO, device node, or directory-like special file). The library only accepts regular files as receipt sources so the digest corresponds to stable on-disk bytes.
Solutions
- Point the receipt argument at an actual regular file on disk
- Check what the path is: ls -la <path> or stat <path> and fix the config/variable
- If reading from a pipe/stdin, first write the content to a temp regular file and validate that
- Regenerate the receipt file if the artifact pipeline left it as a special file
Example fix
# before
receipt_path = '/dev/stdin'
# after
import tempfile, shutil, sys
with tempfile.NamedTemporaryFile(delete=False) as tmp:
shutil.copyfileobj(sys.stdin, tmp)
receipt_path = tmp.name Defensive patterns
Strategy: validation
Validate before calling
import stat, os
md = os.lstat(path)
assert stat.S_ISREG(md.st_mode), f'{path} is not a regular file' Type guard
def is_regular_file(path) -> bool:
import stat, os
try:
return stat.S_ISREG(os.lstat(path).st_mode)
except OSError:
return False Try / catch
try:
validate_artifact_receipt(root)
except ContractError as e:
if 'not a regular file' in str(e):
print(f'Receipt must be a regular file: {e}')
else:
raise Prevention
- Never point receipt paths at /dev/*, pipes, or sockets
- Stat the path before validation in scripts
- Write streamed receipts to a temp regular file first
When it happens
Trigger: Passing a path that is a character device, FIFO/pipe, socket, or other special file as the receipt path to validate_artifact_receipt. This check runs after open+fstat, so it catches files that are special even if they passed a path lookup.
Common situations: Pointing the receipt argument at /dev/stdin, a named pipe used for streaming, a device file, or a directory by mistake in scripts/CI configs.
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
- all overlays must be readable local files
- all takes must be readable local files
- artifact must be a resident regular file
- artifact path escapes output directory
- artifact path must be canonical and absolute
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/5eacfb8cb75ba36b.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/tasteforge/contract.py:78
raise ContractError(f"{label} has invalid {field}")
for value in values:
_validate_media_time(value, source_duration, label=f"{label} {field}")
samples = probe.get("style_samples", [])
if not isinstance(samples, list) or any(not isinstance(sample, dict) for sample in samples):
raise ContractError(f"{label} has invalid style evidence")
for sample in samples:
_validate_media_time(sample.get("time"), source_duration, label=f"{label} style evidence")
def _sha256(path: Path) -> str:
if not hasattr(os, "O_NOFOLLOW"):
raise ContractError("secure receipt validation requires O_NOFOLLOW")
descriptor = os.open(path, os.O_RDONLY | os.O_NOFOLLOW)
digest = hashlib.sha256()
try:
metadata = os.fstat(descriptor)
if not stat.S_ISREG(metadata.st_mode):
raise ContractError(f"receipt source is not a regular file: {path}")
while True:
chunk = os.read(descriptor, 1024 * 1024)
if not chunk:
break
digest.update(chunk)
finally:
os.close(descriptor)
return digest.hexdigest()
def _semantic_signature(spec: dict[str, Any]) -> str:
signature = spec.get("signature", {})
return json.dumps(signature, sort_keys=True, separators=(",", ":"))
def _validate_output_tree(root: Path) -> None:
"""Reject symlinks and special files before parsing bundle content."""
try:View on GitHub (pinned to 8321021c54)