abhigyanpatwari/GitNexus · error · SandboxError

{label} directory target has the wrong type: {relative}

Error message

{label} directory target has the wrong type: {relative}

What it means

Raised by _prepare_clone_target when the caller asked for a directory target (directory=True) and the leaf already exists but is not a directory (e.g. a regular file, socket, or device). The harness refuses to overwrite or follow it; the mount placeholder must be a real directory, so a type mismatch aborts staging.

Source

Thrown at eval/workflow_bench/proposer_sandbox.py:617

            try:
                next_fd = os.open(part, flags | nofollow, dir_fd=current_fd)
            except OSError as exc:
                raise SandboxError(f"{label} target has a non-directory or symlink parent: {relative}") from exc
            os.close(current_fd)
            current_fd = next_fd

        leaf = relative.parts[-1]
        try:
            mode = os.stat(leaf, dir_fd=current_fd, follow_symlinks=False).st_mode
        except FileNotFoundError:
            mode = None
        if mode is not None and stat.S_ISLNK(mode):
            raise SandboxError(f"{label} target cannot be a symlink: {relative}")
        if directory is True:
            if mode is None:
                os.mkdir(leaf, mode=0o700, dir_fd=current_fd)
            elif not stat.S_ISDIR(mode):
                raise SandboxError(f"{label} directory target has the wrong type: {relative}")
        elif directory is False:
            if mode is None:
                file_flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL | nofollow
                file_fd = os.open(leaf, file_flags, 0o600, dir_fd=current_fd)
                os.close(file_fd)
            elif not stat.S_ISREG(mode):
                raise SandboxError(f"{label} file target has the wrong type: {relative}")
        elif mode is not None and not (stat.S_ISREG(mode) or stat.S_ISDIR(mode)):
            raise SandboxError(f"{label} target has the wrong type: {relative}")
    finally:
        os.close(current_fd)
    return clone / Path(*relative.parts)


def stage_task_assets(
    task: Mapping[str, Any],
    *,
    repo: Path,

View on GitHub (pinned to d540b00184)

Solutions

  1. Check the leaf type at the path in the error: `stat -c '%F' <worktree>/<leaf>`.
  2. If a tracked file is colliding, remove it from the repo or change the task target path so the directory placeholder does not overlap the file.
  3. If the collision is generated state, ensure the worktree is freshly created and setup does not write a file at that path.
  4. Reconcile the task's declared target type with what actually lives at that path.

Example fix

// before — task wants a directory but a file is tracked there
target: .vite-temp   # directory=True, but a file .vite-temp exists
// after — remove the tracked file so the dir placeholder can be created
git rm .vite-temp
Defensive patterns

Strategy: validation

Validate before calling

import os, stat
from pathlib import PurePosixPath

def dir_target_ok(clone: Path, relative: str) -> bool:
    parts = PurePosixPath(relative).parts
    pfd = os.open(clone, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW)
    try:
        for p in parts[:-1]:
            nxt = os.open(p, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=pfd)
            os.close(pfd); pfd = nxt
        try:
            mode = os.stat(parts[-1], dir_fd=pfd, follow_symlinks=False).st_mode
            return stat.S_ISDIR(mode)
        except FileNotFoundError:
            return True  # will be created
    finally:
        os.close(pfd)

Try / catch

from .proposer_sandbox import SandboxError

try:
    target = _prepare_clone_target(clone, PurePosixPath(rel), directory=True, label='dep')
except SandboxError:
    # leaf exists but is not a directory; clear or reroute
    raise

Prevention

When it happens

Trigger: _prepare_clone_target(..., directory=True) finds an existing leaf whose mode fails stat.S_ISDIR — for example a task declares a directory-shaped dependency mount but a regular file already sits at that path in the clone.

Common situations: A dependency-snapshot directory path collides with a tracked regular file; a prior run left a file where a directory is now expected; task authoring changed a target from file to directory without clearing the old artifact.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/7733d023cf9c69e2. Report an issue: GitHub.