can1357/oh-my-pi · error
tool bridge is unavailable in this kernel
Error message
tool bridge is unavailable in this kernel
What it means
The Ruby prelude's `OmpBridge` module forwards `tool.<name>(...)` calls to the host process over a loopback HTTP bridge. The bridge URL, bearer token, and session ID are injected via the PI_TOOL_BRIDGE_URL, PI_TOOL_BRIDGE_TOKEN, and PI_TOOL_BRIDGE_SESSION environment variables. `proxy_env` raises when any of the three is missing or empty, meaning the script is running without a live host bridge.
Source
Thrown at packages/coding-agent/src/eval/rb/prelude.rb:290
__omp_emit_status("output", "count" => combined.length, "total_chars" => combined.sum { |r| r["content"].length })
combined
end
# -------------------------------------------------------------------------
# Host tool bridge (loopback HTTP) — `tool.<name>(args)`, completion, agent.
# -------------------------------------------------------------------------
module OmpBridge
INTENT_FIELD = "i"
module_function
def proxy_env
base = ENV["PI_TOOL_BRIDGE_URL"]
token = ENV["PI_TOOL_BRIDGE_TOKEN"]
session = ENV["PI_TOOL_BRIDGE_SESSION"]
if base.nil? || base.empty? || token.nil? || token.empty? || session.nil? || session.empty?
raise "tool bridge is unavailable in this kernel"
end
[base.sub(%r{/+\z}, ""), token, session]
end
def call(name, args)
require "net/http"
require "uri"
base, token, session = proxy_env
uri = URI("#{base}/v1/tool")
payload = JSON.generate("session" => session, "run" => $__omp_current_rid, "name" => name, "args" => args)
http = Net::HTTP.new(uri.hostname, uri.port)
http.open_timeout = 10
http.read_timeout = 7 * 24 * 3600
req = Net::HTTP::Post.new(uri)
req["Content-Type"] = "application/json"
req["Authorization"] = "Bearer #{token}"
req.body = payload
resp = http.request(req)View on GitHub (pinned to 9690622007)
Solutions
- Run the script inside the omp eval kernel so the PI_TOOL_BRIDGE_* environment variables are injected.
- Verify the variables exist before calling bridge functions: `abort 'no bridge' unless ENV['PI_TOOL_BRIDGE_URL']`.
- If spawning subprocesses, forward ENV explicitly so the bridge vars propagate to the child.
- If a tool call is genuinely not needed, guard the call behind a bridge-availability check and take a local fallback path.
Example fix
// before
result = OmpBridge.call('read_file', { 'path' => 'x.txt' }) # env vars missing
// after
if ENV['PI_TOOL_BRIDGE_URL'] && ENV['PI_TOOL_BRIDGE_TOKEN'] && ENV['PI_TOOL_BRIDGE_SESSION']
result = OmpBridge.call('read_file', { 'path' => 'x.txt' })
else
result = File.read('x.txt') rescue nil
end Defensive patterns
Strategy: validation
Validate before calling
BRIDGE_VARS = %w[PI_TOOL_BRIDGE_URL PI_TOOL_BRIDGE_TOKEN PI_TOOL_BRIDGE_SESSION]
bridge_ready = BRIDGE_VARS.all? { |v| ENV[v] && !ENV[v].empty? } Try / catch
begin value = OmpBridge.call(name, args) rescue RuntimeError => e raise unless e.message == 'tool bridge is unavailable in this kernel' value = local_fallback(name, args) end
Prevention
- Always run bridge-dependent scripts inside the omp eval kernel, never via plain `ruby`.
- Check all three PI_TOOL_BRIDGE_* variables at script start and fail fast with a clear message.
- When spawning subprocesses, pass ENV through so bridge vars propagate.
When it happens
Trigger: Invoking any `OmpBridge.call` / `tool.<name>` helper (directly or via `call`) in a Ruby process where PI_TOOL_BRIDGE_URL, PI_TOOL_BRIDGE_TOKEN, or PI_TOOL_BRIDGE_SESSION is unset, nil, or an empty string — e.g. running the prelude outside an omp eval kernel or after the env was stripped (sudo, cron, sanitizing wrapper).
Common situations: Running a Ruby snippet standalone with `ruby script.rb` instead of inside the omp eval runtime; an env filter dropping PI_TOOL_BRIDGE_* variables; spawning a subprocess that does not inherit the kernel env.
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
- tool bridge is unavailable in this kernel
- Ruby kernel unavailable
- query cannot be combined with offset/limit
- Output #{output_id} is not valid JSON: #{e.message}
- Offset #{start_line} is beyond end of output (#{total_lines}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/b0ef0cb8239d00f7.
Report an issue: GitHub.