{"record":{"id":"6e62bf3dea630d39","repo":"abhigyanpatwari/GitNexus","slug":"sandbox-dependencies-entries-require-only-nonblank","errorCode":null,"errorMessage":"sandbox_dependencies entries require only nonblank source and target","messagePattern":"sandbox_dependencies entries require only nonblank source and target","errorType":"exception","errorClass":"SandboxError","httpStatus":null,"severity":"error","filePath":"eval/workflow_bench/task_assets.py","lineNumber":574,"sourceCode":"            if path == other or path in other.parents or other in path.parents:\n                raise SandboxError(f\"sandbox_copy declarations overlap: {path} and {other}\")\n    return declarations, tuple(paths)\n\n\ndef _sandbox_dependency_declarations(\n    task: Mapping[str, Any],\n) -> tuple[_DependencyDeclaration, ...]:\n    raw_declarations = task.get(\"sandbox_dependencies\", [])\n    if not isinstance(raw_declarations, list):\n        raise SandboxError(\"sandbox_dependencies must be a list\")\n    declarations: list[_DependencyDeclaration] = []\n    for item in raw_declarations:\n        if (\n            not isinstance(item, Mapping)\n            or set(item) != {\"source\", \"target\"}\n            or not all(isinstance(item[field], str) and item[field] for field in (\"source\", \"target\"))\n        ):\n            raise SandboxError(\"sandbox_dependencies entries require only nonblank source and target\")\n        source = str(item[\"source\"])\n        target = str(item[\"target\"])\n        source_path = PurePosixPath(source)\n        target_path = PurePosixPath(target)\n        if source_path.is_absolute() or \"..\" in source_path.parts or not source_path.parts:\n            raise SandboxError(f\"dependency source must stay inside the repository: {source_path}\")\n        if target_path.is_absolute() or \"..\" in target_path.parts or not target_path.parts:\n            raise SandboxError(f\"dependency target must stay inside the clone: {target_path}\")\n        _validate_manifest_path(source_path)\n        _validate_manifest_path(target_path)\n        declarations.append(\n            _DependencyDeclaration(\n                source=source,\n                target=target,\n                source_path=source_path,\n                target_path=target_path,\n            )\n        )","sourceCodeStart":556,"sourceCodeEnd":592,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/eval/workflow_bench/task_assets.py#L556-L592","documentation":"Raised by _sandbox_dependency_declarations for each entry that is not a Mapping, or whose set of keys is not exactly {source, target}, or where either field is not a non-blank string. The harness requires each dependency to declare precisely a source and a target and nothing else — extra keys, missing keys, blank values, or non-string types all fail. The strict key-set check (`set(item) != {\"source\", \"target\"}`) prevents typos and stray metadata from silently being ignored.","triggerScenarios":"An entry like `{\"src\": \"a\", \"target\": \"b\"}` (typo: src not source), `{\"source\": \"a\", \"target\": \"b\", \"mode\": \"ro\"}` (extra key), `{\"source\": \"\", \"target\": \"b\"}` (blank source), `{\"source\": \"a\"}` (missing target), or `\"a:b\"` (a string, not a mapping). Also `{\"source\": 123, \"target\": \"b\"}` (non-string).","commonSituations":"Typo in key names from hand-authoring. Copying a schema from another tool that uses `from`/`to` or `path`/`mount`. Adding an unused `readonly` or `mode` field that the strict check rejects. Blank values from incomplete templating.","solutions":["Use exactly the keys `source` and `target` with non-empty string values; remove any extra keys.","Double-check key spelling — `source` not `src`, `target` not `dest`/`to`/`mount`.","Ensure both fields are present and non-blank strings.","Validate each entry with the provided type guard before prepare() (see typeGuard)."],"exampleFix":"// before\n{\"sandbox_dependencies\": [\n  {\"src\": \"node_modules\", \"target\": \"node_modules\", \"readonly\": true}\n]}\n\n// after\n{\"sandbox_dependencies\": [\n  {\"source\": \"node_modules\", \"target\": \"node_modules\"}\n]}","handlingStrategy":"type-guard","validationCode":"from collections.abc import Mapping\n\ndef validate_dependency_entries(task: dict) -> None:\n    for i, item in enumerate(task.get(\"sandbox_dependencies\", [])):\n        if (\n            not isinstance(item, Mapping)\n            or set(item) != {\"source\", \"target\"}\n            or not all(isinstance(item[f], str) and item[f] for f in (\"source\", \"target\"))\n        ):\n            raise ValueError(f\"dependency entry {i} must have only nonblank source and target: {item!r}\")\n\nvalidate_dependency_entries(task)","typeGuard":"from collections.abc import Mapping\n\ndef is_valid_dependency_entry(item: object) -> bool:\n    return (\n        isinstance(item, Mapping)\n        and set(item) == {\"source\", \"target\"}\n        and all(isinstance(item[f], str) and item[f] for f in (\"source\", \"target\"))\n    )","tryCatchPattern":"from eval.workflow_bench.propposer_sandbox import SandboxError\n\ntry:\n    snapshot = cache.prepare(task, repo=repo, resolved_sha=sha)\nexcept SandboxError as exc:\n    if \"require only nonblank source and target\" in str(exc):\n        # fix key names (source/target), remove extras, ensure non-blank\n        raise\n    raise","preventionTips":["Use exactly the keys `source` and `target`; avoid `src`, `dest`, `to`, `from`, `mount`.","Remove any extra metadata keys (the harness rejects unknown fields).","Validate each entry with the type guard before prepare."],"tags":["sandbox","config","validation","dependencies","schema","task-declaration"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}