abhigyanpatwari/GitNexus · error · SandboxError
dependency source must stay inside the repository: {source_p
Error message
dependency source must stay inside the repository: {source_path} What it means
Raised by _sandbox_dependency_declarations when a dependency's `source` path is absolute (starts with '/'), contains a '..' component, or is empty (no parts after PurePosixPath parsing). The source must stay inside the repository because it is opened relative to the repo descriptor via _open_relative — an escaping source would read bytes outside the declared repo identity, breaking snapshot determinism and the security boundary. This is the dependency analogue of the sandbox_copy repository-relative guard.
Source
Thrown at eval/workflow_bench/task_assets.py:580
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)
declarations.append(
_DependencyDeclaration(
source=source,
target=target,
source_path=source_path,
target_path=target_path,
)
)
for index, declaration in enumerate(declarations):
for other in declarations[index + 1 :]:
if (
declaration.target_path == other.target_path
or declaration.target_path in other.target_path.parents
or other.target_path in declaration.target_path.parentsView on GitHub (pinned to d540b00184)
Solutions
- Rewrite each dependency source as a clean repo-relative path with no '..': `node_modules`, `vendor/lib`, not `/usr/lib/node_modules` or `../shared`.
- Compute sources via `os.path.relpath(path, repo_root)` at authoring time and reject results starting with '..'.
- If bytes outside the repo are genuinely needed, copy them into the repo (or a worktree) first so the source is inside.
- Validate with the provided path guard before prepare() (see validationCode).
Example fix
// before
{"sandbox_dependencies": [
{"source": "/usr/local/lib/node_modules", "target": "node_modules"}
]}
// after
{"sandbox_dependencies": [
{"source": "node_modules", "target": "node_modules"}
]} Defensive patterns
Strategy: type-guard
Validate before calling
from pathlib import PurePosixPath
def validate_dependency_sources_relative(task: dict) -> None:
for d in task.get("sandbox_dependencies", []):
sp = PurePosixPath(d["source"])
if sp.is_absolute() or ".." in sp.parts or not sp.parts:
raise ValueError(f"dependency source must stay inside repo: {sp}")
validate_dependency_sources_relative(task) Type guard
from pathlib import PurePosixPath
def dependency_source_is_bounded(raw: str) -> bool:
p = PurePosixPath(raw)
return not p.is_absolute() and bool(p.parts) and ".." not in p.parts 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 "source must stay inside the repository" in str(exc):
# rewrite the source as a repo-relative path
raise
raise Prevention
- Author dependency sources relative to the repo root with no '..'.
- Remember source is repo-relative, target is clone-relative — do not mix them.
- If bytes outside the repo are needed, copy them into the repo first.
When it happens
Trigger: A dependency source like `/abs/path`, `../outside`, `node_modules/../../etc`, or `''`. The check is `source_path.is_absolute() or '..' in source_path.parts or not source_path.parts`.
Common situations: Author pastes an absolute path from outside the repo. A templating layer prefixes '/'. A relative source that walks above the repo root with '..'. Confusing source (repo-relative) with target (clone-relative) and using an absolute path for source.
Related errors
- dependency target must stay inside the clone: {target_path}
- sandbox_copy must be a repository-relative path: {raw!r}
- sandbox_dependencies must be a list
- sandbox_dependencies entries require only nonblank source an
- sandbox dependency targets overlap: {declaration.target} and
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/09348a269ae6c355.
Report an issue: GitHub.