can1357/oh-my-pi · error · RuntimeError
No session - output artifacts unavailable
Error message
No session - output artifacts unavailable
What it means
The prelude's output() writes result artifacts to an artifacts directory taken from PI_ARTIFACTS_DIR, falling back to deriving it from PI_SESSION_FILE (session file minus .jsonl extension). When neither env var is set there is no session context, so it emits an error status and raises RuntimeError 'No session - output artifacts unavailable'. The prelude is designed to run inside an eval session and refuses to guess where artifacts should go.
Source
Thrown at packages/coding-agent/src/eval/py/prelude.py:181
Single ID: str (format='raw'/'stripped') or dict (format='json')
Multiple IDs: list of dict with 'id' and 'content'/'data' keys
Examples:
output('scout_0') # Read as raw text
output('reviewer_0', format='json') # Read with metadata
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] = []
View on GitHub (pinned to 9690622007)
Solutions
- Set PI_ARTIFACTS_DIR (or PI_SESSION_FILE) in the environment before running the code.
- Run the script through the eval harness so it injects the session env vars.
- When spawning subprocesses, pass the parent environment through instead of a fresh env.
- For local development, skip output() and write files to a known directory directly.
Example fix
# before
output(ids=["result"])
# after
import os
os.environ.setdefault("PI_ARTIFACTS_DIR", "/tmp/eval-artifacts")
output(ids=["result"]) Defensive patterns
Strategy: validation
Validate before calling
import os
if not (os.environ.get('PI_ARTIFACTS_DIR') or os.environ.get('PI_SESSION_FILE')):
raise RuntimeError('output() requires PI_ARTIFACTS_DIR or PI_SESSION_FILE in the environment') Type guard
def has_session_env(): return bool(os.environ.get('PI_ARTIFACTS_DIR') or os.environ.get('PI_SESSION_FILE')) Try / catch
try:
output(ids=['result'])
except RuntimeError as e:
if 'No session' in str(e):
# not running under the eval harness — persist locally instead
write_local_artifact()
else:
raise Prevention
- Run prelude scripts through the eval harness so session env vars are injected.
- Never spawn subprocesses with a scrubbed env={}; inherit the parent environment.
- Check PI_ARTIFACTS_DIR/PI_SESSION_FILE at script start and fail fast with a clear message.
- Gate output() calls behind has_session_env() in locally-run code.
When it happens
Trigger: Calling output(ids=...) in a Python process where the eval harness didn't inject PI_ARTIFACTS_DIR or PI_SESSION_FILE — e.g. running the script standalone, spawning a subprocess that doesn't inherit the env, or invoking output() from a non-session REPL.
Common situations: Executing prelude code directly with `python script.py` outside the agent; launching a subprocess with a scrubbed environment (env={}); running the same code locally during development without the harness.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- No artifacts directory found: {artifacts_dir}
- Python kernel unavailable
- Python kernel unavailable
- Protocol paths are not supported by this helper: {path}
- 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/12ad0e03df1d85d6.
Report an issue: GitHub.