{"record":{"id":"888e27364749d309","repo":"antiwork/gumroad","slug":"typia-assert-message-string-await-response-j","errorCode":null,"errorMessage":"typia.assert<{ message: string }>(await response.json()).message","messagePattern":"typia\\.assert<(.+?)>\\(await response\\.json\\(\\)\\)\\.message","errorType":"exception","errorClass":"ResponseError","httpStatus":null,"severity":"error","filePath":"app/javascript/data/installments.ts","lineNumber":187,"sourceCode":"  const response = await request({\n    method: \"POST\",\n    accept: \"json\",\n    url: Routes.internal_installment_non_opener_resend_path(externalId),\n  });\n\n  const json: unknown = await response.json();\n  if (!response.ok) throw new ResponseError(typia.assert<{ error: string }>(json).error);\n  return typia.assert<{ success: boolean }>(json);\n}\n\nexport async function previewInstallment(externalId: string) {\n  const response = await request({\n    method: \"POST\",\n    accept: \"json\",\n    url: Routes.internal_installment_preview_email_path(externalId),\n  });\n\n  if (!response.ok) throw new ResponseError(typia.assert<{ message: string }>(await response.json()).message);\n}\n","sourceCodeStart":169,"sourceCodeEnd":189,"githubUrl":"https://github.com/antiwork/gumroad/blob/afeacbd394069a1cbf0c6c50ee8e900925050370/app/javascript/data/installments.ts#L169-L189","documentation":"previewInstallment POSTs internal_installment_preview_email_path and on non-ok asserts the body is { message: string }, throwing ResponseError with that message. Same dual failure as its sibling at line 176: a well-formed { message } body yields the intended ResponseError, but any other failure body (HTML page, empty body, or a body keyed error) makes typia.assert throw a TypeError from inside the error path.","triggerScenarios":"A 4xx with a JSON { message } body → ResponseError carrying the server text (e.g., 'Installment has no email body'). A 4xx whose body is keyed error — which the sibling resend endpoint uses — or is HTML/empty → typia TypeError on $input.message.","commonSituations":"Two endpoints in the same file expecting different error-body keys; an exception-rendering path that returns HTML while handlers assume JSON; previewing an installment whose email template fails to render server-side.","solutions":["Inspect the failing response body in the Network tab and check the key is message, not error.","Standardize the installment endpoints on one error-body shape, or extract defensively with a type guard instead of typia.assert.","Fix the server render path so JSON-only endpoints never fall through to an HTML error page.","Show e.message (ResponseError) and log TypeError separately — they mean different defects."],"exampleFix":"// before\nif (!response.ok) throw new ResponseError(typia.assert<{ message: string }>(await response.json()).message);\n\n// after\nif (!response.ok) {\n  const json: unknown = await response.json();\n  const message =\n    typeof json === 'object' && json !== null && 'message' in json && typeof (json as { message: unknown }).message === 'string'\n      ? (json as { message: string }).message\n      : 'Could not preview this installment.';\n  throw new ResponseError(message);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"const hasMessageBody = (json: unknown): json is { message: string } =>\n  typeof json === 'object' && json !== null && 'message' in json && typeof (json as { message: unknown }).message === 'string';","tryCatchPattern":"try {\n  await previewInstallment(externalId);\n} catch (e) {\n  if (!(e instanceof ResponseError)) {\n    console.error('Unexpected error body', e); // typia TypeError — body wasn't { message: string }\n    showError('Could not preview this installment.');\n  } else {\n    showError(e.message);\n  }\n}","preventionTips":["Check which key (message vs error) this endpoint's failure body actually uses before asserting.","Keep a shared defensive extractor for error bodies across the installments module.","Ensure server exception handling renders JSON, never HTML, on json endpoints."],"tags":["installments","internal-tools","typia","schema-validation","error-handling"],"backgroundTag":"api-error-response-body","analyzedSha":"afeacbd394069a1cbf0c6c50ee8e900925050370","analyzedAt":"2026-08-21T17:58:52.159Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}