{"record":{"id":"585711770c291980","repo":"tinyhumansai/openhuman","slug":"provider-surfaces-list-queue-unexpected-empty-res","errorCode":null,"errorMessage":"provider_surfaces_list_queue: unexpected empty response","messagePattern":"provider_surfaces_list_queue: unexpected empty response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"app/src/services/api/providerSurfacesApi.ts","lineNumber":13,"sourceCode":"import type { RespondQueueList } from '../../types/providerSurfaces';\nimport { callCoreRpc } from '../coreRpcClient';\n\ninterface ProviderSurfacesQueueEnvelope {\n  data?: RespondQueueList;\n  result?: { data?: RespondQueueList };\n}\n\nconst EMPTY_QUEUE: RespondQueueList = { items: [], count: 0 };\n\nfunction parseQueueEnvelope(raw: unknown): RespondQueueList {\n  if (!raw || typeof raw !== 'object') {\n    throw new Error('provider_surfaces_list_queue: unexpected empty response');\n  }\n\n  const envelope = raw as ProviderSurfacesQueueEnvelope & { error?: { message?: string } };\n  if (envelope.error) {\n    throw new Error(envelope.error.message ?? 'Core RPC returned an error');\n  }\n  const candidate = envelope.result?.data ?? envelope.data;\n  if (!candidate || !Array.isArray(candidate.items) || typeof candidate.count !== 'number') {\n    return EMPTY_QUEUE;\n  }\n  return candidate;\n}\n\nexport const providerSurfacesApi = {\n  async listQueue(): Promise<RespondQueueList> {\n    const raw = await callCoreRpc<unknown>({ method: 'openhuman.provider_surfaces_list_queue' });\n    return parseQueueEnvelope(raw);\n  },","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/app/src/services/api/providerSurfacesApi.ts#L1-L31","documentation":"Thrown by parseQueueEnvelope() in providerSurfacesApi when the raw value returned by callCoreRpc('openhuman.provider_surfaces_list_queue') is null/undefined or not an object. At this point the RPC already resolved — the core answered with nothing (a void/None result) instead of a queue envelope. The strict non-object check distinguishes 'core returned empty' from the softer case of a well-formed envelope with a malformed payload, which returns EMPTY_QUEUE instead.","triggerScenarios":"Core's provider_surfaces controller returns Ok(()) on some path (queue disabled, feature not compiled via DomainSet); version skew where the method exists but returns a bare list the transport wraps as undefined; JSON-RPC success with no result field reaching the client.","commonSituations":"Desktop surfaces/queue feature turned off in the running core's domain set; an older standalone core (OPENHUMAN_CORE_REUSE_EXISTING=1); a core bug where the handler returns before populating the envelope.","solutions":["Restart/update the core so provider_surfaces_list_queue returns its result envelope.","Confirm the provider-surfaces domain is enabled in the running core (check GET /schema for the method and its return type).","Inspect the core log for the handler's execution — an early-return path will show why nothing was produced.","If running an external core for debugging, build it from the same commit as the UI."],"exampleFix":"// before\nif (!raw || typeof raw !== 'object') {\n  throw new Error('provider_surfaces_list_queue: unexpected empty response');\n}\n\n// after — degrade to empty queue for read-only list UIs instead of throwing\nif (!raw || typeof raw !== 'object') {\n  console.warn('provider_surfaces_list_queue: empty response, assuming no queue');\n  return EMPTY_QUEUE;\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":"function isQueueResponseShape(raw: unknown): boolean {\n  return Boolean(raw) && typeof raw === 'object';\n}","tryCatchPattern":"let queue: RespondQueueList;\ntry {\n  queue = await providerSurfacesApi.listQueue();\n} catch (e) {\n  if (e instanceof Error && e.message === 'provider_surfaces_list_queue: unexpected empty response') {\n    queue = { items: [], count: 0 }; // read-only surface: degrade to empty\n  } else throw e;\n}","preventionTips":["For list-only UI surfaces, degrade to an empty list rather than throwing.","Verify the method exists in the core's /schema when wiring new panels.","Keep core and UI versions aligned."],"tags":["core-rpc","provider-surfaces","empty-response","response-validation"],"backgroundTag":"empty-rpc-response","analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}