{"record":{"id":"9b30ca925ddbc3c2","repo":"can1357/oh-my-pi","slug":"at-least-one-output-id-is-required","errorCode":null,"errorMessage":"At least one output ID is required","messagePattern":"At least one output ID is required","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/eval/py/prelude.py","lineNumber":191,"sourceCode":"        # Prefer PI_ARTIFACTS_DIR so subagents resolve through the parent's\n        # shared artifacts dir; fall back to deriving from PI_SESSION_FILE\n        # for legacy callers / top-level sessions where the two coincide.\n        artifacts_dir = os.environ.get(\"PI_ARTIFACTS_DIR\")\n        if not artifacts_dir:\n            session_file = os.environ.get(\"PI_SESSION_FILE\")\n            if not session_file:\n                _emit_status(\"output\", error=\"No session file available\")\n                raise RuntimeError(\"No session - output artifacts unavailable\")\n            artifacts_dir = session_file.rsplit(\".\", 1)[0]  # Strip .jsonl extension\n        if not Path(artifacts_dir).exists():\n            _emit_status(\n                \"output\", error=\"Artifacts directory not found\", path=artifacts_dir\n            )\n            raise RuntimeError(f\"No artifacts directory found: {artifacts_dir}\")\n\n        if not ids:\n            _emit_status(\"output\", error=\"No IDs provided\")\n            raise ValueError(\"At least one output ID is required\")\n\n        if query and (offset is not None or limit is not None):\n            _emit_status(\"output\", error=\"query cannot be combined with offset/limit\")\n            raise ValueError(\"query cannot be combined with offset/limit\")\n\n        results: list[dict] = []\n        not_found: list[str] = []\n\n        for output_id in ids:\n            output_path = Path(artifacts_dir) / f\"{output_id}.md\"\n            if not output_path.exists():\n                not_found.append(output_id)\n                continue\n\n            raw_content = output_path.read_text(encoding=\"utf-8\")\n            raw_lines = raw_content.splitlines()\n            total_lines = len(raw_lines)\n","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/eval/py/prelude.py#L173-L209","documentation":"The `output()` helper in the eval Python prelude reads tool-output artifacts stored as `<id>.md` files in the run's artifacts directory. It throws this ValueError when called with an empty or missing `ids` argument, because there is nothing to look up. The library refuses to guess which artifact you meant or return an empty result set.","triggerScenarios":"Calling `output()` with no arguments, `output(ids=[])`, or `output(ids=None)` — any call where `ids` is falsy.","commonSituations":"Building the id list programmatically from a variable that turned out empty (e.g. a filtered list of tool-call ids matched nothing), or copying an example call and dropping the ids argument assuming a default.","solutions":["Pass at least one output id: `output([\"tool_1\"])` or `output(\"tool_1\")`.","If ids are computed, check the list is non-empty before calling and handle the empty case in your eval script.","If you don't know the ids, inspect the artifacts directory (`<session>.jsonl` path minus extension) or enumerate available outputs via the host tooling first."],"exampleFix":"// before\nids = [c[\"id\"] for c in calls if c[\"ok\"]]\nresult = output(ids)\n\n// after\nids = [c[\"id\"] for c in calls if c[\"ok\"]]\nif not ids:\n    raise SystemExit(\"no successful tool calls to inspect\")\nresult = output(ids)","handlingStrategy":"validation","validationCode":"if not ids:\n    raise SystemExit(\"output() called with no ids; nothing to read\")","typeGuard":null,"tryCatchPattern":"try:\n    result = output(ids)\nexcept ValueError as e:\n    if \"At least one output ID\" in str(e):\n        result = None","preventionTips":["Always build ids from an actual source (session tool calls) rather than typing them by hand.","Guard computed id lists for emptiness before calling output().","Never call output() with no arguments expecting a default listing behavior."],"tags":["python","validation","argument-error","eval"],"backgroundTag":"missing-required-argument","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}