OpenBMB/ChatDev · error · ValueError

_context is required for uv tools

Error message

_context is required for uv tools

What it means

WorkspaceCommandContext (the context object backing uv_run and install_python_packages) requires the runtime-injected _context dict. Constructing it with None — because the tool was called without context injection or the parameter was dropped — raises ValueError immediately. The context carries python_workspace_root, which these tools cannot function without.

Source

Thrown at functions/function_calling/uv_related.py:43

def _build_timeout_message(step: str | None, timeout_value: float, stdout: str, stderr: str) -> str:
    """Create a descriptive timeout error message with optional output preview."""

    label = "uv command"
    if step:
        label = f"{label} ({step})"
    message = f"{label} timed out after {timeout_value} seconds"
    preview = _trim_output_preview(stdout, stderr)
    if preview:
        return f"{message}. Last output: {preview}"
    return message


class WorkspaceCommandContext:
    """Resolve the workspace root from the injected runtime context."""

    def __init__(self, ctx: Dict[str, Any] | None):
        if ctx is None:
            raise ValueError("_context is required for uv tools")
        self.workspace_root = self._require_workspace(ctx.get("python_workspace_root"))
        self._raw_ctx = ctx

    @staticmethod
    def _require_workspace(raw_path: Any) -> Path:
        if raw_path is None:
            raise ValueError("python_workspace_root missing from _context")
        path = Path(raw_path).expanduser().resolve()
        path.mkdir(parents=True, exist_ok=True)
        return path

    def resolve_under_workspace(self, relative_path: str | Path) -> Path:
        candidate = Path(relative_path)
        absolute = candidate if candidate.is_absolute() else self.workspace_root / candidate
        absolute = absolute.expanduser().resolve()
        if self.workspace_root not in absolute.parents and absolute != self.workspace_root:
            raise ValueError("script path is outside workspace root")
        return absolute

View on GitHub (pinned to 4fb2db0ea9)

Solutions

  1. Ensure the tool is invoked through the runtime that injects _context (include the _context parameter in the tool-call payload)
  2. In tests, pass a dict containing python_workspace_root pointing at a temp directory
  3. Check the adapter/bridge forwards _context when registering these tools

Example fix

# before
ctx = WorkspaceCommandContext(None)
# after
ctx = WorkspaceCommandContext({"python_workspace_root": "/tmp/ws"})
Defensive patterns

Strategy: validation

Validate before calling

if _context is None:
    _context = {"python_workspace_root": str(tempfile.mkdtemp())}  # e.g. in tests
uv_run(script="run.py", _context=_context)

Type guard

def has_context(ctx) -> bool:
    return isinstance(ctx, dict)

Try / catch

try:
    uv_run(script="run.py", _context=_context)
except ValueError as e:
    if "_context is required" in str(e):
        raise RuntimeError("tool invoked without runtime context injection") from e
    raise

Prevention

When it happens

Trigger: Invoking uv_run or install_python_packages without the injected _context argument; manually instantiating WorkspaceCommandContext(None) in tests; a tool-adapter layer that fails to forward the runtime context dict.

Common situations: Unit tests constructing tool objects directly; refactoring the function-calling layer so _context is no longer passed through; calling the tool from a framework that does not support context injection.

Related errors


AI-assisted analysis of OpenBMB/ChatDev@4fb2db0ea9 (2026-08-27). Data as JSON: /api/errors/abf14a6529c9672d. Report an issue: GitHub.