agentscope-ai/agentscope · error · ValueError
{label} must be a real directory: {path}
Error message
{label} must be a real directory: {path} What it means
_directory_identity requires every mount source to be a real directory (not a symlink, not a file). It raises ValueError with the offending label and path; __init__ and the pre-execution validator both call it, so the error surfaces either at construction or at first run.
Source
Thrown at src/agentscope/workspace/_bubblewrap/_bubblewrap_backend.py:507
)
except ValueError as exc:
raise RuntimeError(
"host_cache_dir was removed or replaced before execution.",
) from exc
if identity != self._host_cache_identity:
raise RuntimeError(
"host_cache_dir was replaced before execution.",
)
@staticmethod
def _directory_identity(
path: str,
*,
label: str,
) -> tuple[int, int]:
"""Return a stable identity for a real directory mount source."""
if os.path.islink(path) or not os.path.isdir(path):
raise ValueError(f"{label} must be a real directory: {path}")
stat_result = os.stat(path, follow_symlinks=False)
return stat_result.st_dev, stat_result.st_ino
@staticmethod
def _paths_overlap(left: str, right: str) -> bool:
"""Return whether either real path contains the other."""
left_real = os.path.realpath(left)
right_real = os.path.realpath(right)
try:
common = os.path.commonpath([left_real, right_real])
except ValueError:
return False
return common in (left_real, right_real)
def _base_env(self) -> dict[str, str]:
"""Environment visible to sandboxed commands."""
path_parts = [
f"{SANDBOX_WORKDIR}/.agentscope/.venv/bin",View on GitHub (pinned to e90f1c7592)
Solutions
- Replace the symlink with a real directory (or bind mount) and pass the real path
- Create the directory first: os.makedirs(path, exist_ok=True)
- Verify with os.path.islink(path) == False and os.path.isdir(path) before constructing
Example fix
# before
ws = BubblewrapWorkspace(host_workdir='/data/link-to-ws') # symlink
# after
os.makedirs('/data/ws', exist_ok=True)
ws = BubblewrapWorkspace(host_workdir='/data/ws') Defensive patterns
Strategy: type-guard
Validate before calling
import os
for p in (workdir, tmpdir, cache_dir):
if p is not None:
assert not os.path.islink(p) and os.path.isdir(p), f'bad mount source: {p}' Type guard
def is_real_dir(p: str) -> bool:
return not os.path.islink(p) and os.path.isdir(p) Try / catch
except ValueError as e:
if 'must be a real directory' in str(e):
os.makedirs(p, exist_ok=True) # then retry construction Prevention
- Replace workspace symlinks with real directories or bind mounts
- Create all mount dirs before constructing the backend
When it happens
Trigger: Passing host_workdir/host_tmpdir/host_cache_dir that is a symlink to a directory, a regular file, or a nonexistent path.
Common situations: Symlinked workspace dirs (common in dotfile-managed setups or Docker volumes), typos in paths, or pointing at a path created later by another service.
Related errors
- host_cache_dir must not be a symbolic link.
- {left_name} must not overlap {right_name}.
- host_cache_dir must be a directory.
- {label} was removed or replaced before execution.
- host_cache_dir was removed or replaced before execution.
AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28).
Data as JSON: /api/errors/f704edf9b2e66717.
Report an issue: GitHub.