{"record":{"id":"fc9c8e981ab2c4c3","repo":"stablyai/orca","slug":"unexpected-listapps-response-json-stringify-res","errorCode":null,"errorMessage":"Unexpected listApps response: ${JSON.stringify(result)}","messagePattern":"Unexpected listApps response: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"config/scripts/macos-computer-helper-owner-loss-benchmark.mjs","lineNumber":293,"sourceCode":"    if (capabilities?.protocolVersion !== 1) {\n      throw new Error(`Unexpected helper handshake: ${JSON.stringify(capabilities)}`)\n    }\n    return { authenticated: capabilities.protocolVersion === 1, sidecar, helper }\n  } catch (error) {\n    sidecar.child.kill('SIGKILL')\n    await stopProcess(helper)\n    throw error\n  }\n}\n\nasync function exerciseActiveRequests(sidecar) {\n  const latencies = []\n  const startedAt = performance.now()\n  for (let index = 0; index < ACTIVE_REQUEST_COUNT; index += 1) {\n    const requestStartedAt = performance.now()\n    const result = await requestSidecar(sidecar, 10_000 + index, 'listApps')\n    if (!Array.isArray(result?.apps)) {\n      throw new Error(`Unexpected listApps response: ${JSON.stringify(result)}`)\n    }\n    latencies.push(performance.now() - requestStartedAt)\n  }\n  const totalMs = performance.now() - startedAt\n  return {\n    totalMs,\n    requestsPerSecond: (ACTIVE_REQUEST_COUNT * 1_000) / totalMs,\n    medianLatencyMs: median(latencies),\n    p95LatencyMs: percentile(latencies, 0.95),\n    maxLatencyMs: Math.max(...latencies)\n  }\n}\n\nasync function verifyGracefulClose() {\n  const { sidecar, helper } = await startAuthenticatedSession()\n  try {\n    const startedAt = performance.now()\n    sidecar.child.disconnect()","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/macos-computer-helper-owner-loss-benchmark.mjs#L275-L311","documentation":"exerciseActiveRequests drives ACTIVE_REQUEST_COUNT listApps calls against the sidecar and expects each result to have an array-typed apps field. It throws on the first response whose shape is wrong (missing apps or non-array), treating any deviation as a sidecar malfunction during the load exercise.","triggerScenarios":"The listApps RPC returned an error envelope, a partial/empty result, or a payload where apps was renamed/restructured in the current sidecar version.","commonSituations":"Sidecar crashed mid-exercise and returned an error object, a version where listApps nests apps under a different key, or the helper died under load so the sidecar could not enumerate apps.","solutions":["Inspect the serialized result in the message — if it is an error envelope, address the underlying sidecar/helper failure.","Re-run with a smaller ACTIVE_REQUEST_COUNT to see if the failure is load-induced or immediate.","If the apps field was renamed in a newer version, update the Array.isArray(result?.apps) check to the new shape."],"exampleFix":"// before\nif (!Array.isArray(result?.apps)) {\n  throw new Error(`Unexpected listApps response: ${JSON.stringify(result)}`)\n}\n\n// after\nif (!Array.isArray(result?.apps)) {\n  throw new Error(`Unexpected listApps response at index ${index}: ${JSON.stringify(result).slice(0, 300)}`)\n}","handlingStrategy":"validation","validationCode":"function assertListApps(result, index) {\n  if (!Array.isArray(result?.apps)) {\n    throw new Error(`listApps[${index}] malformed: ${JSON.stringify(result).slice(0,300)}`)\n  }\n}","typeGuard":"const isListAppsResult = (r) => r && Array.isArray(r.apps)","tryCatchPattern":"try {\n  await exerciseActiveRequests(sidecar)\n} catch (e) {\n  if (/Unexpected listApps/.test(e.message)) { /* check sidecar liveness, reduce load, retry */ }\n  throw e\n}","preventionTips":["Reduce ACTIVE_REQUEST_COUNT to isolate load-induced failures from shape errors.","If the apps field was renamed, update the guard to the new shape.","Monitor sidecar liveness between requests so a crash is caught explicitly."],"tags":["rpc","validation","response","helper","load"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}