can1357/oh-my-pi · error · RuntimeError

tool bridge is unavailable in this kernel

Error message

tool bridge is unavailable in this kernel

What it means

The prelude's `tool` proxy forwards calls over an HTTP bridge to the host process, configured entirely through environment variables: `PI_TOOL_BRIDGE_URL`, `PI_TOOL_BRIDGE_TOKEN`, and `PI_TOOL_BRIDGE_SESSION`. This RuntimeError is raised when any of those variables is missing or empty, meaning the Python kernel was not launched with a live tool bridge (e.g. run outside the agent's eval harness).

Source

Thrown at packages/coding-agent/src/eval/py/prelude.py:376

        current = data
        for token_type, value in tokens:
            if token_type == "index":
                if not isinstance(current, list) or value >= len(current):
                    return None
                current = current[value]
            elif token_type == "key":
                if not isinstance(current, dict) or value not in current:
                    return None
                current = current[value]

        return current

    def _tool_proxy_from_env() -> tuple[str, str, str]:
        base = os.environ.get("PI_TOOL_BRIDGE_URL")
        token = os.environ.get("PI_TOOL_BRIDGE_TOKEN")
        session = os.environ.get("PI_TOOL_BRIDGE_SESSION")
        if not base or not token or not session:
            raise RuntimeError("tool bridge is unavailable in this kernel")
        return (base.rstrip("/"), token, session)

    import urllib.error, urllib.request

    # urllib discovers environment and macOS SystemConfiguration proxies. This
    # host-owned loopback endpoint must always connect directly.
    _BRIDGE_OPENER = urllib.request.build_opener(urllib.request.ProxyHandler({}))

    def _bridge_call(name: str, args: dict):
        """POST one request to the host tool bridge and return its `value`."""
        base, token, session = _tool_proxy_from_env()
        _run_id_getter = globals().get("__omp_current_run_id__")
        _run_id = (
            _run_id_getter()
            if callable(_run_id_getter)
            else globals().get("__omp_run_id__")
        )
        payload = json.dumps(

View on GitHub (pinned to 9690622007)

Solutions

  1. Run the Python code through the agent's eval harness so the host injects the bridge env vars.
  2. Verify the three variables exist in the kernel: `import os; print(bool(os.environ.get('PI_TOOL_BRIDGE_URL')), bool(os.environ.get('PI_TOOL_BRIDGE_TOKEN')), bool(os.environ.get('PI_TOOL_BRIDGE_SESSION')))`.
  3. If running standalone, replace `tool.*` calls with local equivalents (direct file reads, local computation) instead of host tool calls.

Example fix

// before
result = tool.read_file({"path": "src/main.ts"})  # fails outside harness

// after
import os
if os.environ.get("PI_TOOL_BRIDGE_URL"):
    result = tool.read_file({"path": "src/main.ts"})
else:
    with open("src/main.ts") as f:
        result = f.read()
Defensive patterns

Strategy: fallback

Validate before calling

import os
bridge_ready = all(os.environ.get(k) for k in ("PI_TOOL_BRIDGE_URL", "PI_TOOL_BRIDGE_TOKEN", "PI_TOOL_BRIDGE_SESSION"))

Try / catch

try:
    result = tool.read_file({"path": p})
except RuntimeError as e:
    if "tool bridge is unavailable" in str(e):
        result = local_read(p)  # local fallback

Prevention

When it happens

Trigger: Calling any `tool.<name>(...)` from a Python kernel that wasn't spawned by the eval harness with bridge env vars injected, or after the host cleared/failed to set the env for the kernel process.

Common situations: Running the prelude in a plain `python`/REPL or notebook started manually; the host crashed or restarted and relaunched the kernel without the bridge env; env vars stripped by a wrapper (systemd, docker, CI sanitizer).

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/2cff828739c4f8ec. Report an issue: GitHub.