headroomlabs-ai/headroom · error · Error

Headroom OpenCode transport shim loaded without HEADROOM_OPE

Error message

Headroom OpenCode transport shim loaded without HEADROOM_OPENCODE_TRANSPORT_PROXY_URL

What it means

The OpenCode transport shim (built handler.js) is a side-effect-only module: it reads HEADROOM_OPENCODE_TRANSPORT_PROXY_URL at import time and throws if it is unset, because installing the transport without a proxy target is a programming error. Since it throws during module evaluation, the whole Node child process load fails, not just one request.

Source

Thrown at plugins/opencode/hook-shim/handler.js:5

import { installHeadroomTransport } from "../dist/index.js";

const proxyUrl = process.env.HEADROOM_OPENCODE_TRANSPORT_PROXY_URL;
if (!proxyUrl) {
  throw new Error("Headroom OpenCode transport shim loaded without HEADROOM_OPENCODE_TRANSPORT_PROXY_URL");
}

installHeadroomTransport({ proxyUrl });

View on GitHub (pinned to 322425c43b)

Solutions

  1. Set and export the variable before starting OpenCode / the process that loads the shim: export HEADROOM_OPENCODE_TRANSPORT_PROXY_URL=http://127.0.0.1:8787
  2. Ensure child processes inherit it (pass env: { ...process.env } when spawning)
  3. If the shim should not load in some contexts, gate the hook registration on the env var being present rather than letting the module throw

Example fix

# before
HEADROOM_OPENCODE_TRANSPORT_PROXY_URL=http://127.0.0.1:8787 opencode  # not exported to children in some spawn paths

# after
export HEADROOM_OPENCODE_TRANSPORT_PROXY_URL=http://127.0.0.1:8787
opencode
Defensive patterns

Strategy: validation

Validate before calling

// Gate before anything can import the shim
const proxyUrl = process.env.HEADROOM_OPENCODE_TRANSPORT_PROXY_URL;
if (!proxyUrl) {
  throw new Error(
    "HEADROOM_OPENCODE_TRANSPORT_PROXY_URL is not set — the OpenCode transport shim must not be loaded"
  );
}
// only now safe to import / register the hook
import("./hook-shim/handler.js");

Type guard

function shimEnvPresent(env: NodeJS.ProcessEnv): env is NodeJS.ProcessEnv & {
  HEADROOM_OPENCODE_TRANSPORT_PROXY_URL: string;
} {
  return typeof env.HEADROOM_OPENCODE_TRANSPORT_PROXY_URL === "string"
    && env.HEADROOM_OPENCODE_TRANSPORT_PROXY_URL.length > 0;
}

Prevention

When it happens

Trigger: Any mechanism that loads plugins/opencode/hook-shim/handler.js (OpenCode hook/plugin loader, a wheel install's shim path) in a Node process where HEADROOM_OPENCODE_TRANSPORT_PROXY_URL is not set — unset, empty string, or set only in a parent shell that did not export it.

Common situations: Env var set with 'VAR=value' instead of 'export VAR=value'; child process spawned with a sanitized env; hook registered globally so it loads in every OpenCode session, including ones started without the proxy; name typo in the variable.

Related errors


AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15). Data as JSON: /api/errors/3be66097d3796c31. Report an issue: GitHub.