{"record":{"id":"a1fbac82819ba4d9","repo":"abhigyanpatwari/GitNexus","slug":"sandbox-copy-must-be-a-list","errorCode":null,"errorMessage":"sandbox_copy must be a list","messagePattern":"sandbox_copy must be a list","errorType":"exception","errorClass":"SandboxError","httpStatus":null,"severity":"error","filePath":"eval/workflow_bench/sanitized_graph.py","lineNumber":89,"sourceCode":"            )\n        self.assets.materialize(clone)\n\n\ndef _is_restricted_path(value: str) -> bool:\n    relative = PurePosixPath(value)\n    if relative.is_absolute() or not relative.parts or \"..\" in relative.parts:\n        return False\n    return (\n        relative.parts[0] == \".gitnexus\" or relative == HIDDEN_HARNESS_PATH or HIDDEN_HARNESS_PATH in relative.parents\n    )\n\n\ndef validate_no_prebuilt_graph_assets(task: Mapping[str, Any]) -> None:\n    \"\"\"Reject declarations that could reintroduce an unsanitized graph/oracle.\"\"\"\n\n    sandbox_copy = task.get(\"sandbox_copy\", [])\n    if not isinstance(sandbox_copy, list):\n        raise SandboxError(\"sandbox_copy must be a list\")\n    for value in sandbox_copy:\n        if isinstance(value, str) and _is_restricted_path(value):\n            raise SandboxError(f\"sandbox_copy cannot import prebuilt graph or harness data: {value}\")\n\n    dependencies = task.get(\"sandbox_dependencies\", [])\n    if not isinstance(dependencies, list):\n        raise SandboxError(\"sandbox_dependencies must be a list\")\n    for item in dependencies:\n        if not isinstance(item, Mapping):\n            continue\n        for field in (\"source\", \"target\"):\n            value = item.get(field)\n            if isinstance(value, str) and _is_restricted_path(value):\n                raise SandboxError(f\"sandbox dependency cannot expose prebuilt graph or harness data: {value}\")\n\n\ndef _replace_control_file(root: Path, name: str, payload: bytes) -> None:\n    path = root / name","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/sanitized_graph.py#L71-L107","documentation":"Type guard in validate_no_prebuilt_graph_assets. The task spec's 'sandbox_copy' field must be a list; anything else (a string, a mapping, null with a non-default sentinel) is rejected because the harness cannot iterate it safely and a malformed value could hide a restricted path. The default is an empty list, so omitting the field is fine.","triggerScenarios":"A task YAML/JSON declares sandbox_copy as a scalar (e.g. 'sandbox_copy: .gitnexus/oracle.json') or as a mapping instead of a sequence of strings. validate_no_prebuilt_graph_assets runs the isinstance check before scanning entries.","commonSituations":"Author typo (single value instead of one-element list); a YAML parser turning an unquoted special value into a non-string scalar; schema drift after a task-format change; copy-pasting a dependency-style mapping into sandbox_copy.","solutions":["Make sandbox_copy a sequence in the task spec: 'sandbox_copy: [\"path/one\", \"path/two\"]' or YAML block list with each entry a string.","If you intended a single copy, still wrap it in a list: 'sandbox_copy: [\"path/one\"]'.","Validate the task file locally: load it and assert isinstance(spec.get('sandbox_copy', []), list) before running.","Check the task schema documentation for the current expected shape of sandbox_copy."],"exampleFix":"# before (tasks.scenarios.yaml)\nsandbox_copy: src/fixtures/oracle.json\n# after\nsandbox_copy:\n  - src/fixtures/oracle.json","handlingStrategy":"type-guard","validationCode":"import yaml\nfrom pathlib import Path\n\ntask = yaml.safe_load(Path(\"task.yaml\").read_text())\nif \"sandbox_copy\" in task and not isinstance(task[\"sandbox_copy\"], list):\n    raise SystemExit(f\"sandbox_copy must be a list, got {type(task['sandbox_copy']).__name__}\")\n# validate_no_prebuilt_graph_assets(task)  # full harness check","typeGuard":"from collections.abc import Mapping\n\ndef sandbox_copy_well_formed(task: Mapping) -> bool:\n    sc = task.get(\"sandbox_copy\", [])\n    return isinstance(sc, list) and all(isinstance(v, str) for v in sc)","tryCatchPattern":"from eval.workflow_bench.sanitized_graph import validate_no_prebuilt_graph_assets, SandboxError\n\ntry:\n    validate_no_prebuilt_graph_assets(task)\nexcept SandboxError as exc:\n    if \"sandbox_copy must be a list\" in str(exc):\n        log.error(\"task.sandbox_copy must be a YAML/JSON list of strings\")\n    raise","preventionTips":["Always declare sandbox_copy as a sequence, even for one entry.","Lint task specs in CI with a schema that requires sandbox_copy to be an array of strings.","Run validate_no_prebuilt_graph_assets on every task before submission."],"tags":["sandbox","task-spec","validation","type-error","workflow-bench"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}