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

  1. Verify the app was launched with a valid --remote-debugging-port and that remoteDebugPort matches it
  2. Retry after a short delay if the app/CDP server is still starting
  3. curl http://127.0.0.1:<port>/json/list to confirm the endpoint responds
  4. 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

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


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/8e6dc2c73896b1dc. Report an issue: GitHub.