can1357/oh-my-pi · error · RuntimeError
No artifacts directory found: {artifacts_dir}
Error message
No artifacts directory found: {artifacts_dir} What it means
output() resolves the artifacts directory (from PI_ARTIFACTS_DIR or PI_SESSION_FILE) and requires that the directory already exist on disk; if it doesn't, it emits an error status and raises RuntimeError 'No artifacts directory found: <path>'. The harness is expected to have created the directory when the session started — output() never creates it implicitly.
Source
Thrown at packages/coding-agent/src/eval/py/prelude.py:187
output('scout_0', query='.files[0]') # Extract JSON field
output('scout_0', offset=10, limit=20) # Lines 10-29
output('scout_0', 'reviewer_1') # Read multiple outputs
"""
# Prefer PI_ARTIFACTS_DIR so subagents resolve through the parent's
# shared artifacts dir; fall back to deriving from PI_SESSION_FILE
# for legacy callers / top-level sessions where the two coincide.
artifacts_dir = os.environ.get("PI_ARTIFACTS_DIR")
if not artifacts_dir:
session_file = os.environ.get("PI_SESSION_FILE")
if not session_file:
_emit_status("output", error="No session file available")
raise RuntimeError("No session - output artifacts unavailable")
artifacts_dir = session_file.rsplit(".", 1)[0] # Strip .jsonl extension
if not Path(artifacts_dir).exists():
_emit_status(
"output", error="Artifacts directory not found", path=artifacts_dir
)
raise RuntimeError(f"No artifacts directory found: {artifacts_dir}")
if not ids:
_emit_status("output", error="No IDs provided")
raise ValueError("At least one output ID is required")
if query and (offset is not None or limit is not None):
_emit_status("output", error="query cannot be combined with offset/limit")
raise ValueError("query cannot be combined with offset/limit")
results: list[dict] = []
not_found: list[str] = []
for output_id in ids:
output_path = Path(artifacts_dir) / f"{output_id}.md"
if not output_path.exists():
not_found.append(output_id)
continue
View on GitHub (pinned to 9690622007)
Solutions
- Create the directory before calling output(): os.makedirs(artifacts_dir, exist_ok=True).
- Point PI_ARTIFACTS_DIR at a directory that exists for the current session.
- If PI_SESSION_FILE was moved/renamed, ensure the sibling artifacts directory matches its new path.
- Re-run through the harness so it recreates the session's artifacts directory.
Example fix
# before output(ids=["result"]) # artifacts dir cleaned up # after import os artifacts = os.environ["PI_ARTIFACTS_DIR"] os.makedirs(artifacts, exist_ok=True) output(ids=["result"])
Defensive patterns
Strategy: validation
Validate before calling
import os
from pathlib import Path
dir_ = os.environ.get('PI_ARTIFACTS_DIR') or os.environ.get('PI_SESSION_FILE', '').rsplit('.', 1)[0]
if dir_ and not Path(dir_).exists():
os.makedirs(dir_, exist_ok=True) Type guard
def artifacts_ready():
d = os.environ.get('PI_ARTIFACTS_DIR') or os.environ.get('PI_SESSION_FILE', '').rsplit('.', 1)[0]
return bool(d) and Path(d).is_dir() Try / catch
try:
output(ids=['result'])
except RuntimeError as e:
if str(e).startswith('No artifacts directory found'):
os.makedirs(e.args[0].rsplit(': ', 1)[-1], exist_ok=True)
output(ids=['result'])
else:
raise Prevention
- Create PI_ARTIFACTS_DIR during session setup, before any cell runs.
- If you move or rename PI_SESSION_FILE, move the sibling artifacts directory too.
- Avoid tmp-dir cleanup jobs that delete live session artifacts.
- Call os.makedirs(dir, exist_ok=True) defensively before output().
When it happens
Trigger: PI_ARTIFACTS_DIR pointing at a deleted/never-created directory, PI_SESSION_FILE set to a path whose sibling artifacts dir (session path minus .jsonl) was cleaned up, a stale env var left over from a previous session, or a typo in the configured path.
Common situations: Re-running a script after tmp cleanup removed the artifacts dir; copying PI_SESSION_FILE/PI_ARTIFACTS_DIR between machines or containers; resuming an old session file whose artifacts directory was garbage-collected.
Related errors
- No session - output artifacts unavailable
- Failed to move artifacts and rollback: ${rollbackErr instanc
- Cleanse session could not be persisted
- Session file not found: ${resolved}
- Output not found: {', '.join(not_found)}\n\nAvailable output
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/24110100e0f9d4e5.
Report an issue: GitHub.