jackwener/OpenCLI · error · Error

Failed to fetch CDP targets: HTTP ${response.status}

Error message

Failed to fetch CDP targets: HTTP ${response.status}

What it means

fetchTargets in targets.js throws a plain Error when the HTTP GET to `${endpoint}/json` (the Chrome DevTools Protocol target list) returns a non-2xx status within its 5-second AbortSignal timeout. The status code is embedded in the message to indicate why the CDP endpoint refused or failed the request.

Source

Thrown at clis/trae-cn/targets.js:35

}

function targetValue(target) {
  const title = String(target?.title || '').trim();
  const workspace = title.match(/—\s*(.+)$/)?.[1]?.trim();
  return workspace || title || String(target?.url || '').trim();
}

function matchesTarget(target, wanted) {
  if (!wanted) return false;
  const needle = String(wanted).toLowerCase();
  const haystack = `${target.title || ''} ${target.url || ''}`.toLowerCase();
  return haystack.includes(needle);
}

async function fetchTargets(endpoint) {
  const response = await fetch(`${endpoint}/json`, { signal: AbortSignal.timeout(5000) });
  if (!response.ok) {
    throw new Error(`Failed to fetch CDP targets: HTTP ${response.status}`);
  }
  const targets = await response.json();
  return Array.isArray(targets) ? targets : [];
}

async function probeTargetActivity(target, maxChars) {
  if (!target.webSocketDebuggerUrl) return null;
  const bridge = new CDPBridge();
  try {
    const page = await bridge.connect({ cdpEndpoint: target.webSocketDebuggerUrl, timeout: 3, surface: 'adapter' });
    return await page.evaluate(activityScript(maxChars));
  } catch {
    return null;
  } finally {
    await bridge.close().catch(() => {});
  }
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the port with `opencli trae-cn targets` against the actual remote-debugging port; confirm with `curl http://127.0.0.1:<port>/json`.
  2. Ensure Trae CN is running with remote debugging enabled (correct --remote-debugging-port).
  3. Fix OPENCLI_CDP_ENDPOINT if it points at the wrong port or protocol (http vs https).
  4. Bypass any HTTP proxy for localhost (NO_PROXY=127.0.0.1,localhost).

Example fix

// before
export OPENCLI_CDP_ENDPOINT=http://127.0.0.1:8080  // app port, not CDP
// after
curl http://127.0.0.1:39240/json   # confirm CDP responds
export OPENCLI_CDP_ENDPOINT=http://127.0.0.1:39240
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight: confirm the CDP /json endpoint is reachable before calling fetchTargets
async function assertCdpHealthy(endpoint) {
  const res = await fetch(`${endpoint.replace(/\/$/, '')}/json`, { signal: AbortSignal.timeout(5000) });
  if (!res.ok) throw new Error(`CDP endpoint ${endpoint} unhealthy: HTTP ${res.status}`);
  const t = await res.json();
  if (!Array.isArray(t)) throw new Error('Endpoint did not return a CDP target list');
}

Type guard

function isCdpTargetList(v) {
  return Array.isArray(v) && v.every(t => t && typeof t === 'object' && 'id' in t && 'webSocketDebuggerUrl' in t);
}

Try / catch

async function fetchTargetsWithRetry(endpoint, attempts = 3) {
  for (let i = 0; i < attempts; i++) {
    try {
      return await fetchTargets(endpoint);
    } catch (e) {
      if (i === attempts - 1) throw e;
      if (!/Failed to fetch CDP targets|HTTP 5/.test(e.message)) throw e;
      await new Promise(r => setTimeout(r, 1000 * (i + 1)));
    }
  }
}

Prevention

When it happens

Trigger: Hitting an endpoint that is not a CDP debugger (wrong port serving a different app), a proxy returning 403/502, or the DevTools server rejecting /json after a Chrome/Electron version change that disabled the targets endpoint.

Common situations: OPENCLI_CDP_ENDPOINT pointing at the app's HTTP port instead of the remote-debugging port; corporate proxy intercepting localhost calls; Trae CN relaunched without --remote-debugging-port so another service owns the port.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/5a44098273cee1e0. Report an issue: GitHub.