{"record":{"id":"504819cc0ed0261d","repo":"musistudio/claude-code-router","slug":"ccr-management-service-is-unavailable-make-sure-t","errorCode":null,"errorMessage":"CCR management service is unavailable. Make sure the CCR app or ccr ui command is running, then retry.","messagePattern":"CCR management service is unavailable\\. Make sure the CCR app or ccr ui command is running, then retry\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ui/src/web-client-bridge.ts","lineNumber":34,"sourceCode":"    headers: {\n      \"content-type\": \"application/json\",\n      ...(webAuthToken ? { [webAuthHeader]: webAuthToken } : {})\n    },\n    method: \"POST\"\n  });\n  let payload: RpcResponse | undefined;\n  try {\n    payload = await response.json() as RpcResponse;\n  } catch {\n    payload = undefined;\n  }\n  if (!response.ok || !payload?.ok) {\n    const message = payload && !payload.ok\n      ? payload.error.message\n      : response.status === 404\n        ? \"CCR management service is unavailable. Make sure the CCR app or ccr ui command is running, then retry.\"\n        : `CCR web API failed with HTTP ${response.status}`;\n    throw new Error(message);\n  }\n  return payload.value;\n}\n\nfunction trimTrailingUndefined(args: unknown[]): unknown[] {\n  let end = args.length;\n  while (end > 0 && args[end - 1] === undefined) {\n    end -= 1;\n  }\n  return end === args.length ? args : args.slice(0, end);\n}\n\nfunction readWebAuthToken(): string {\n  const tokenFromUrl = readWebAuthTokenFromUrl();\n  if (tokenFromUrl) {\n    writeStoredWebAuthToken(tokenFromUrl);\n    return tokenFromUrl;\n  }","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/ui/src/web-client-bridge.ts#L16-L52","documentation":"Thrown by the web client bridge rpc() helper when a call to the CCR management web API returns HTTP 404, meaning the management endpoint is not being served. The bridge expects the CCR desktop app or the `ccr ui` CLI command to be running and exposing the API.","triggerScenarios":"Any bridge call (e.g. selectPluginDirectory, applyClaudeAppGateway) when the CCR app / ccr ui process is not running, was restarted on a different port, or the UI was loaded from a URL where the /api routes are absent.","commonSituations":"Opening the web UI in a plain browser without starting `ccr ui`; the CCR backend crashed or exited while the UI tab stayed open; proxying/routing that strips the API path so requests hit a 404; version mismatch where the endpoint path changed.","solutions":["Start the CCR app or run `ccr ui` and confirm the process is alive, then retry","Reload the web UI so it reconnects to the currently running service","Verify nothing (proxy, base path, firewall) is rewriting the API URL to a nonexistent route","Restart the CCR service if it crashed mid-session"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Before bridging, probe the management API:\nconst res = await fetch(managementBaseUrl, { method: \"HEAD\" }).catch(() => null);\nif (!res || res.status === 404) { await startCcrUi(); /* then retry */ }","typeGuard":null,"tryCatchPattern":"try { await bridge.selectPluginDirectory(dir); } catch (e) { if (e instanceof Error && e.message.includes(\"CCR management service is unavailable\")) { await ensureCcrRunning(); return retry(); } throw e; }","preventionTips":["Health-check the management API on UI boot and show a reconnect banner","Auto-restart `ccr ui` when the endpoint 404s","Keep the UI and backend versions in lockstep to avoid path changes"],"tags":["network","service-unavailable","http-404","rpc"],"backgroundTag":"backend-service-unavailable","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}