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

  1. Run the script inside the omp eval kernel so the PI_TOOL_BRIDGE_* environment variables are injected.
  2. Verify the variables exist before calling bridge functions: `abort 'no bridge' unless ENV['PI_TOOL_BRIDGE_URL']`.
  3. If spawning subprocesses, forward ENV explicitly so the bridge vars propagate to the child.
  4. 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

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


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