abhigyanpatwari/GitNexus · error · SandboxError
transcript artifact source is not the parent event stream
Error message
transcript artifact source is not the parent event stream
What it means
Within the validated metadata dict, the 'source' field must equal runner_sessions.PARENT_EVENT_STREAM_SOURCE ('parent-captured-stream-json'). Only transcripts the harness itself captured from the parent event stream are admissible as evidence; an agent-exported or third-party stream could have been tampered with.
Source
Thrown at eval/workflow_bench/evolve.py:334
except OSError as exc:
raise SandboxError(f"results artifact parent is unavailable: {current}: {exc}") from exc
if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode):
raise SandboxError(f"results artifact parent must be a real directory: {current}")
if transcript and stat.S_IMODE(metadata.st_mode) & 0o077:
raise SandboxError(f"transcript artifact parent must be owner-only: {current}")
return root / Path(*relative.parts)
def _transcript_artifact_metadata(metadata: Any) -> tuple[str, str, int]:
"""Validate transcript metadata without touching any host path."""
if not isinstance(metadata, dict) or set(metadata) != {"path", "sha256", "bytes", "source"}:
raise SandboxError("transcript artifact metadata must contain only path, sha256, bytes, and source")
relative = metadata["path"]
expected_digest = metadata["sha256"]
expected_size = metadata["bytes"]
if metadata["source"] != runner_sessions.PARENT_EVENT_STREAM_SOURCE:
raise SandboxError("transcript artifact source is not the parent event stream")
if not isinstance(relative, str) or not re.fullmatch(r"[0-9a-f]{64}", str(expected_digest)):
raise SandboxError("transcript artifact metadata is malformed")
if not isinstance(expected_size, int) or isinstance(expected_size, bool):
raise SandboxError("transcript artifact byte count must be an integer")
if expected_size < 0 or expected_size > runner.MAX_TRANSCRIPT_BYTES:
raise SandboxError("transcript artifact exceeds the bounded run-output limit")
return relative, expected_digest, expected_size
def _normalized_transcript_artifact_path(relative_value: str) -> str:
"""Apply the transcript path contract without touching the filesystem."""
relative = PurePosixPath(relative_value)
if (
relative.is_absolute()
or len(relative.parts) != 2
or relative.parts[0] != "transcripts"
or any(part in {"", ".", ".."} for part in relative.parts)View on GitHub (pinned to d540b00184)
Solutions
- Set source to the exact constant value 'parent-captured-stream-json'.
- Import the constant rather than hard-coding: `from eval.workflow_bench.runner_sessions import PARENT_EVENT_STREAM_SOURCE`.
- If you genuinely have a new provenance, add and validate it as a first-class source in runner_sessions before using it.
Example fix
# before
{"path": "transcripts/r.json", "sha256": "<64hex>", "bytes": 12, "source": "agent-exported-json"}
# after
from eval.workflow_bench.runner_sessions import PARENT_EVENT_STREAM_SOURCE
row = {"path": "transcripts/r.json", "sha256": "<64hex>", "bytes": 12, "source": PARENT_EVENT_STREAM_SOURCE} Defensive patterns
Strategy: validation
Validate before calling
from eval.workflow_bench.runner_sessions import PARENT_EVENT_STREAM_SOURCE
def source_is_parent_stream(metadata: dict) -> bool:
return metadata.get("source") == PARENT_EVENT_STREAM_SOURCE Type guard
from eval.workflow_bench.runner_sessions import PARENT_EVENT_STREAM_SOURCE
def has_parent_stream_source(metadata: dict) -> bool:
return isinstance(metadata, dict) and metadata.get("source") == PARENT_EVENT_STREAM_SOURCE Prevention
- Import PARENT_EVENT_STREAM_SOURCE; never hard-code the string.
- Only the parent-event-stream capture path may write transcript rows.
- Reject foreign/agent-exported transcripts at ingestion.
When it happens
Trigger: source = 'agent-exported-json', 'cli-transcript', an empty string, or any value other than the exact constant; a forked runner wrote transcripts with a different provenance tag.
Common situations: Mixing transcript sources; a runner fork that changed the tag; copy-paste producing a typo in the constant.
Related errors
- {label} must be a real non-symlink directory: {path}
- {label} contains an unsafe path component: {relative}
- {label} must be a regular non-symlink file: {path}
- {label} changed while opening: {path}
- unsafe results artifact path: {relative_value!r}
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/48449cc4c9420002.
Report an issue: GitHub.