different-ai/openwork · error · Error
CDP target list failed: HTTP ${response.status}
Error message
CDP target list failed: HTTP ${response.status} What it means
listCdpTargets queries Electron's local Chrome DevTools Protocol endpoint (`/json/list` on the 127.0.0.1 remote-debugging port) to enumerate debuggable targets. Any non-OK HTTP status (404, 503, connection rejected at HTTP layer after fetch succeeds) raises this error with the status code embedded. The call is bounded by a 1s AbortSignal.timeout.
Source
Thrown at apps/desktop/electron/browser-panel.mjs:128
console.warn("[browser] failed to route blocked main-window navigation", error);
});
}
function cdpBrowserUrl() {
return `http://127.0.0.1:${remoteDebugPort}`;
}
function browserTargetMarkerUrl(tabId) {
const marker = `openwork-browser-tab:${tabId}`;
const html = `<!doctype html><title>${marker}</title><meta name="openwork-browser-tab" content="${tabId}"><body>${marker}</body>`;
return `data:text/html;charset=utf-8,${encodeURIComponent(html)}`;
}
async function listCdpTargets() {
if (!remoteDebugPort || remoteDebugPort <= 0) return [];
// loopback-fetch: CDP discovery targets Electron's local remote debugging port on 127.0.0.1.
const response = await fetch(`${cdpBrowserUrl()}/json/list`, { signal: AbortSignal.timeout(1000) });
if (!response.ok) throw new Error(`CDP target list failed: HTTP ${response.status}`);
const targets = await response.json();
return Array.isArray(targets) ? targets : [];
}
async function resolveBrowserCdpTargetId(tabId) {
const marker = encodeURIComponent(`openwork-browser-tab:${tabId}`);
const deadline = Date.now() + BROWSER_TARGET_RESOLVE_TIMEOUT_MS;
while (Date.now() < deadline) {
const targets = await listCdpTargets().catch(() => []);
const target = targets.find((candidate) => (
candidate?.type === "page" &&
typeof candidate.id === "string" &&
typeof candidate.url === "string" &&
candidate.url.includes(marker)
));
if (target?.id) return target.id;
await new Promise((resolve) => setTimeout(resolve, BROWSER_TARGET_RESOLVE_INTERVAL_MS));
}View on GitHub (pinned to 2b7df46e8a)
Solutions
- Verify the app was launched with a valid --remote-debugging-port and that remoteDebugPort matches it
- Retry after a short delay if the app/CDP server is still starting
- curl http://127.0.0.1:<port>/json/list to confirm the endpoint responds
- Handle non-OK statuses gracefully upstream (return [] instead of throwing) if target discovery is best-effort
Example fix
// before
const response = await fetch(`${cdpBrowserUrl()}/json/list`, { signal: AbortSignal.timeout(1000) });
if (!response.ok) throw new Error(`CDP target list failed: HTTP ${response.status}`);
// after: tolerate transient unavailability
const response = await fetch(`${cdpBrowserUrl()}/json/list`, { signal: AbortSignal.timeout(1000) });
if (!response.ok) return []; // treat as "no targets yet" and let caller retry Defensive patterns
Strategy: fallback
Validate before calling
// Probe CDP before relying on target discovery
const probe = await fetch(`${cdpBrowserUrl()}/json/version`, { signal: AbortSignal.timeout(1000) }).catch(() => null);
const cdpReady = probe?.ok === true; Try / catch
try {
const targets = await listCdpTargets();
} catch (err) {
if (String(err.message).startsWith("CDP target list failed:")) {
// CDP not ready or disabled; degrade gracefully and retry with backoff
await sleep(500);
const targets = await listCdpTargets().catch(() => []);
}
} Prevention
- Launch Electron with a real --remote-debugging-port and keep remoteDebugPort in sync
- Retry /json/list with short backoff during app startup
- curl http://127.0.0.1:<port>/json/list when diagnosing port/proxy issues
- Treat target discovery as best-effort: return [] on non-OK instead of failing the panel
When it happens
Trigger: fetch to `${cdpBrowserUrl()}/json/list` returned response.ok === false — remote-debugging port not serving CDP, wrong port, devtools disabled in this Electron build, or the endpoint temporarily unavailable during startup/shutdown.
Common situations: App launched without --remote-debugging-port so the port probes wrong service; Electron started but CDP not yet listening; security software proxying the loopback port; remoteDebugPort configured from a stale value after restart.
Related errors
- Could not resolve built-in browser CDP target.
- request_failed
- Electron desktop helper is unavailable: ${command}
- Electron desktop helper is unavailable: ${prop}
- Failed to open browser
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/8e6dc2c73896b1dc.
Report an issue: GitHub.