{"record":{"id":"088c504ea9e86158","repo":"stablyai/orca","slug":"invalid-reset-response-from-host","errorCode":null,"errorMessage":"Invalid reset response from host","messagePattern":"Invalid reset response from host","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mobile/src/components/codex-reset-credit.ts","lineNumber":160,"sourceCode":"function scopesEqual(\n  left: CodexResetCreditExpectedScope,\n  right: CodexResetCreditExpectedScope\n): boolean {\n  return (\n    left.target.runtime === right.target.runtime &&\n    left.target.wslDistro === right.target.wslDistro &&\n    left.accountId === right.accountId &&\n    left.accountRevision === right.accountRevision &&\n    left.offerRevision === right.offerRevision\n  )\n}\n\nfunction decodeResetResult(\n  value: unknown,\n  expectedScope: CodexResetCreditExpectedScope\n): CodexResetCreditRpcResult {\n  if (!value || typeof value !== 'object' || Array.isArray(value)) {\n    throw new Error('Invalid reset response from host')\n  }\n  const result = value as Record<string, unknown>\n  const scope = CodexResetCreditExpectedScopeSchema.safeParse(result.scope)\n  if (!scope.success || !scopesEqual(scope.data, expectedScope)) {\n    throw new Error('Invalid reset response from host')\n  }\n  const snapshot = decodeAccountsSnapshot(result.snapshot)\n  if (result.status === 'rejectedBeforeProvider') {\n    const reason = result.reason\n    if (\n      result.retryDisposition !== 'discardAttempt' ||\n      result.outcome !== undefined ||\n      (reason !== 'targetChanged' &&\n        reason !== 'accountChanged' &&\n        reason !== 'accountRevisionChanged' &&\n        reason !== 'accountRuntimeChanged' &&\n        reason !== 'offerUnavailable' &&\n        reason !== 'offerChanged')","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/mobile/src/components/codex-reset-credit.ts#L142-L178","documentation":"First of four sibling guards in decodeResetResult(): rejects the host's reset-credit response if value is null/undefined, not an object, or an array. The Codex reset-credit flow needs a plain object envelope ({scope, snapshot, status/outcome, ...}); anything else is treated as a malformed wire payload and aborts decoding before deeper field checks run.","triggerScenarios":"accounts.consumeCodexResetCredit returns null, undefined, a primitive (string/number), or an array instead of the expected result object.","commonSituations":"Host bug returning the wrong shape, a relay/proxy mangling the response, a version skew where the host returns a bare error string on an unhandled path, or a mock/stub returning [] during testing.","solutions":["Inspect the actual RPC result value the host returned for consumeCodexResetCredit.","Fix the host handler to always return the documented result object shape.","If integrating a stub, return an object with the expected keys, not a primitive/array.","Reproduce by logging `value` before the guard."],"exampleFix":"// before\nif (!value || typeof value !== 'object' || Array.isArray(value)) {\n  throw new Error('Invalid reset response from host')\n}\n\n// after — name the shape problem\nif (!value || typeof value !== 'object' || Array.isArray(value)) {\n  throw new Error(`Invalid reset response from host: expected object, got ${Array.isArray(value) ? 'array' : typeof value}`)\n}","handlingStrategy":"validation","validationCode":"function isPlainObject(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\nif (!isPlainObject(value)) {\n  throw new Error(`Invalid reset response from host: expected object, got ${Array.isArray(value) ? 'array' : typeof value}`)\n}","typeGuard":"function isResetResultEnvelope(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v)\n}","tryCatchPattern":"try {\n  const decoded = decodeResetResult(raw, expectedScope)\n} catch (err) {\n  // Treat as a malformed wire response; re-fetch snapshot and abort the reset UX\n  setResetError('Reset response was malformed. Refresh and retry.')\n}","preventionTips":["Have the host handler always return the documented object envelope, even on error paths.","Log the raw value shape when this guard trips.","Cover the decoder with unit tests for null/array/primitive inputs."],"tags":["mobile","rpc","validation","codex","reset-credit","wire-format"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}