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
- Run the Python code through the agent's eval harness so the host injects the bridge env vars.
- 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')))`.
- 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
- Only use tool.* inside kernels spawned by the eval harness.
- Check the three PI_TOOL_BRIDGE_* env vars before the first tool call and branch to a local path otherwise.
- Beware wrappers (docker, CI, systemd) that strip environment variables from child processes.
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
- Python kernel unavailable
- Python kernel unavailable
- Protocol paths are not supported by this helper: {path}
- No session - output artifacts unavailable
- bridge call {name!r}: non-JSON response: {body[:200]!r}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/2cff828739c4f8ec.
Report an issue: GitHub.