abhigyanpatwari/GitNexus · error · SandboxError
sandbox_dependencies must be a list
Error message
sandbox_dependencies must be a list
What it means
Raised by _sandbox_dependency_declarations when the task's `sandbox_dependencies` field exists but is not a list. This is the top-level type gate for dependency declarations, evaluated before any per-entry validation. An absent field defaults to `[]` (accepted); a present-but-wrong-type field (string, dict, number) is rejected.
Source
Thrown at eval/workflow_bench/task_assets.py:566
for raw in declarations:
relative = PurePosixPath(raw)
if relative.is_absolute() or not relative.parts or ".." in relative.parts:
raise SandboxError(f"sandbox_copy must be a repository-relative path: {raw!r}")
_validate_manifest_path(relative)
paths.append(relative)
for index, path in enumerate(paths):
for other in paths[index + 1 :]:
if path == other or path in other.parents or other in path.parents:
raise SandboxError(f"sandbox_copy declarations overlap: {path} and {other}")
return declarations, tuple(paths)
def _sandbox_dependency_declarations(
task: Mapping[str, Any],
) -> tuple[_DependencyDeclaration, ...]:
raw_declarations = task.get("sandbox_dependencies", [])
if not isinstance(raw_declarations, list):
raise SandboxError("sandbox_dependencies must be a list")
declarations: list[_DependencyDeclaration] = []
for item in raw_declarations:
if (
not isinstance(item, Mapping)
or set(item) != {"source", "target"}
or not all(isinstance(item[field], str) and item[field] for field in ("source", "target"))
):
raise SandboxError("sandbox_dependencies entries require only nonblank source and target")
source = str(item["source"])
target = str(item["target"])
source_path = PurePosixPath(source)
target_path = PurePosixPath(target)
if source_path.is_absolute() or ".." in source_path.parts or not source_path.parts:
raise SandboxError(f"dependency source must stay inside the repository: {source_path}")
if target_path.is_absolute() or ".." in target_path.parts or not target_path.parts:
raise SandboxError(f"dependency target must stay inside the clone: {target_path}")
_validate_manifest_path(source_path)
_validate_manifest_path(target_path)View on GitHub (pinned to d540b00184)
Solutions
- Wrap dependency declarations in a list, even for a single entry: `[{"source": "...", "target": "..."}]`.
- Omit the field entirely if there are no dependencies — both absent and `[]` are valid.
- Validate the task schema before prepare() (see validationCode).
- If templating, ensure the template always emits an array even for one element.
Example fix
// before
{"sandbox_dependencies": {"source": "node_modules", "target": "node_modules"}}
// after
{"sandbox_dependencies": [{"source": "node_modules", "target": "node_modules"}]} Defensive patterns
Strategy: type-guard
Validate before calling
def validate_sandbox_dependencies_list(task: dict) -> None:
raw = task.get("sandbox_dependencies", [])
if not isinstance(raw, list):
raise ValueError("sandbox_dependencies must be a list")
validate_sandbox_dependencies_list(task) Type guard
from typing import Any
def is_sandbox_dependencies_list(value: Any) -> bool:
return value is None or isinstance(value, list) or value == [] Try / catch
from eval.workflow_bench.propposer_sandbox import SandboxError
try:
snapshot = cache.prepare(task, repo=repo, resolved_sha=sha)
except SandboxError as exc:
if "sandbox_dependencies must be a list" in str(exc):
# wrap the value in a list, or omit the field
raise
raise Prevention
- Always author sandbox_dependencies as a list, even for a single dependency.
- Omit the field when there are no dependencies.
- Validate the task schema before prepare.
When it happens
Trigger: Task JSON has `"sandbox_dependencies": {"source": "a", "target": "b"}` (a single dict instead of a list of dicts), or `"sandbox_dependencies": "node_modules"` (a bare string), or any non-list scalar. The check is `if not isinstance(raw_declarations, list)`.
Common situations: Author writes a single dependency as a dict instead of wrapping it in a list. Schema drift from a tool that emits a single object for a one-element array. Copy-paste from a config format that allows a bare value.
Related errors
- sandbox_dependencies entries require only nonblank source an
- sandbox_copy must be a list of nonblank repository-relative
- dependency source must stay inside the repository: {source_p
- dependency target must stay inside the clone: {target_path}
- sandbox dependency targets overlap: {declaration.target} and
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/7e1538069165dd0c.
Report an issue: GitHub.