headroomlabs-ai/headroom · error · Error
Headroom proxy startup is disabled
Error message
Headroom proxy startup is disabled
What it means
ensureProxyUrl() on the OpenClaw engine requires a Headroom proxy, but no proxy URL has been resolved yet and auto-start did not produce a startup promise. ensureProxyStarted() only creates proxyStartupPromise when auto-start is enabled/configured; when it is disabled, the method throws this error immediately. It means the caller wants proxy routing without having provided a running proxy or enabled the engine to start one.
Source
Thrown at plugins/openclaw/src/engine.ts:337
// a missing proxy cannot become a process-level unhandled rejection.
void this.proxyStartupPromise.catch(() => {});
}
onProxyReady(listener: (proxyUrl: string) => void | Promise<void>): () => void {
this.proxyReadyListeners.add(listener);
return () => {
this.proxyReadyListeners.delete(listener);
};
}
async ensureProxyUrl(): Promise<string> {
if (this.proxyUrl) {
return this.proxyUrl;
}
this.ensureProxyStarted();
if (!this.proxyStartupPromise) {
throw new Error("Headroom proxy startup is disabled");
}
return this.proxyStartupPromise;
}
private async notifyProxyReady(proxyUrl: string): Promise<void> {
for (const listener of this.proxyReadyListeners) {
try {
await listener(proxyUrl);
} catch (error) {
this.logger.warn(`Headroom proxy ready listener failed: ${error}`);
}
}
}
}
View on GitHub (pinned to 322425c43b)
Solutions
- Enable proxy auto-start in the engine configuration so ensureProxyStarted() creates a startup promise
- Or point the engine at an already-running proxy (set proxyUrl in config / resolve it via the proxy manager first) so ensureProxyUrl returns the cached URL
- Or start the Headroom proxy out-of-band and register its URL with the engine before any code path calls ensureProxyUrl()
Example fix
// before: autoStart not enabled, no proxyUrl set
await engine.ensureProxyUrl(); // throws
// after: either enable autoStart
engine.configure({ proxy: { autoStart: true } });
await engine.ensureProxyUrl();
// or supply a running proxy explicitly
engine.configure({ proxy: { proxyUrl: "http://127.0.0.1:8787" } }); Defensive patterns
Strategy: validation
Validate before calling
// Call before any code path can hit ensureProxyUrl()
function canEnsureProxy(engine: { proxyUrl?: string }, config: { autoStart?: boolean }): boolean {
return Boolean(engine.proxyUrl) || config.autoStart === true;
}
if (!canEnsureProxy(engine, engineConfig)) {
throw new Error("Configure proxyUrl or enable autoStart before requesting the proxy");
} Type guard
function isProxyReady(engine: { proxyUrl?: string }): engine is { proxyUrl: string } {
return typeof engine.proxyUrl === "string" && engine.proxyUrl.length > 0;
} Try / catch
try {
const url = await engine.ensureProxyUrl();
} catch (e) {
if (e instanceof Error && e.message.includes("startup is disabled")) {
// config gap: enable autoStart or provide a running proxy URL
throw new Error("Proxy required but auto-start disabled: set proxyUrl or autoStart");
}
throw e;
} Prevention
- Validate at construction time: assert config has either proxyUrl or autoStart enabled
- Resolve the proxy URL once during startup and fail fast, instead of lazily inside request paths
- Add a config schema check that rejects 'no proxyUrl and autoStart false' combinations early
When it happens
Trigger: Calling engine.ensureProxyUrl() when engine.proxyUrl is unset (no proxy previously resolved) and the engine's configuration has proxy start/autoStart disabled, so ensureProxyStarted() leaves proxyStartupPromise undefined.
Common situations: Integrating OpenClaw with an externally managed Headroom proxy but forgetting to configure its URL; disabling autoStart in a locked-down environment and then calling an API that transparently needs the proxy; ordering bug where ensureProxyUrl is called before the config that enables startup is applied.
Related errors
- Service reachable at ${explicitUrl}, but it does not appear
- Remote Headroom proxy not reachable at ${explicitUrl}. Ensur
- Headroom proxy not reachable at ${explicitUrl}. Ensure the p
- Headroom proxy not detected on default endpoints (${defaultC
- proxyPort must be an integer between 1 and 65535
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/d7e72fbd3a03fb7b.
Report an issue: GitHub.