stablyai/orca · error · Error

Unexpected listApps response: ${JSON.stringify(result)}

Error message

Unexpected listApps response: ${JSON.stringify(result)}

What it means

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.

Source

Thrown at config/scripts/macos-computer-helper-owner-loss-benchmark.mjs:293

    if (capabilities?.protocolVersion !== 1) {
      throw new Error(`Unexpected helper handshake: ${JSON.stringify(capabilities)}`)
    }
    return { authenticated: capabilities.protocolVersion === 1, sidecar, helper }
  } catch (error) {
    sidecar.child.kill('SIGKILL')
    await stopProcess(helper)
    throw error
  }
}

async function exerciseActiveRequests(sidecar) {
  const latencies = []
  const startedAt = performance.now()
  for (let index = 0; index < ACTIVE_REQUEST_COUNT; index += 1) {
    const requestStartedAt = performance.now()
    const result = await requestSidecar(sidecar, 10_000 + index, 'listApps')
    if (!Array.isArray(result?.apps)) {
      throw new Error(`Unexpected listApps response: ${JSON.stringify(result)}`)
    }
    latencies.push(performance.now() - requestStartedAt)
  }
  const totalMs = performance.now() - startedAt
  return {
    totalMs,
    requestsPerSecond: (ACTIVE_REQUEST_COUNT * 1_000) / totalMs,
    medianLatencyMs: median(latencies),
    p95LatencyMs: percentile(latencies, 0.95),
    maxLatencyMs: Math.max(...latencies)
  }
}

async function verifyGracefulClose() {
  const { sidecar, helper } = await startAuthenticatedSession()
  try {
    const startedAt = performance.now()
    sidecar.child.disconnect()

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Inspect the serialized result in the message — if it is an error envelope, address the underlying sidecar/helper failure.
  2. Re-run with a smaller ACTIVE_REQUEST_COUNT to see if the failure is load-induced or immediate.
  3. If the apps field was renamed in a newer version, update the Array.isArray(result?.apps) check to the new shape.

Example fix

// before
if (!Array.isArray(result?.apps)) {
  throw new Error(`Unexpected listApps response: ${JSON.stringify(result)}`)
}

// after
if (!Array.isArray(result?.apps)) {
  throw new Error(`Unexpected listApps response at index ${index}: ${JSON.stringify(result).slice(0, 300)}`)
}
Defensive patterns

Strategy: validation

Validate before calling

function assertListApps(result, index) {
  if (!Array.isArray(result?.apps)) {
    throw new Error(`listApps[${index}] malformed: ${JSON.stringify(result).slice(0,300)}`)
  }
}

Type guard

const isListAppsResult = (r) => r && Array.isArray(r.apps)

Try / catch

try {
  await exerciseActiveRequests(sidecar)
} catch (e) {
  if (/Unexpected listApps/.test(e.message)) { /* check sidecar liveness, reduce load, retry */ }
  throw e
}

Prevention

When it happens

Trigger: The listApps RPC returned an error envelope, a partial/empty result, or a payload where apps was renamed/restructured in the current sidecar version.

Common situations: 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.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/fc9c8e981ab2c4c3. Report an issue: GitHub.