{"record":{"id":"374a5df4ae928722","repo":"vercel/ai","slug":"code-mode-protocol-error-374a5d","errorCode":"CODE_MODE_PROTOCOL_ERROR","errorMessage":"Code mode approval response is malformed.","messagePattern":"Code mode approval response is malformed\\.","errorType":"exception","errorClass":"CodeModeProtocolError","httpStatus":null,"severity":"error","filePath":"packages/code-mode/src/approval.ts","lineNumber":31,"sourceCode":"  payload: CodeModeInterruptPayload,\n): payload is CodeModeApprovalInterruptPayload {\n  return payload.kind === CODE_MODE_TOOL_APPROVAL_KIND;\n}\n\nexport function assertCodeModeApprovalResponse(\n  value: unknown,\n): asserts value is CodeModeApprovalResponse {\n  if (\n    typeof value !== 'object' ||\n    value === null ||\n    Array.isArray(value) ||\n    typeof (value as { approvalId?: unknown }).approvalId !== 'string' ||\n    typeof (value as { approved?: unknown }).approved !== 'boolean' ||\n    ('reason' in value &&\n      (value as { reason?: unknown }).reason !== undefined &&\n      typeof (value as { reason?: unknown }).reason !== 'string')\n  ) {\n    throw new CodeModeProtocolError(\n      'Code mode approval response is malformed.',\n    );\n  }\n}\n\nexport function normalizeApprovalResolution(\n  resolution: unknown,\n): CodeModeApprovalResolution {\n  if (\n    typeof resolution !== 'object' ||\n    resolution === null ||\n    Array.isArray(resolution) ||\n    typeof (resolution as { approved?: unknown }).approved !== 'boolean' ||\n    ('reason' in resolution &&\n      (resolution as { reason?: unknown }).reason !== undefined &&\n      typeof (resolution as { reason?: unknown }).reason !== 'string')\n  ) {\n    throw new CodeModeProtocolError(","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/code-mode/src/approval.ts#L13-L49","documentation":"This CodeModeProtocolError is thrown by assertCodeModeApprovalResponse when the value passed as an approval response fails structural validation. A valid response must be a non-null, non-array object with a string `approvalId`, a boolean `approved`, and an optional string `reason`. The library throws this to enforce the code-mode approval protocol contract, since an unexpected shape would silently corrupt the approval workflow.","triggerScenarios":"Passing a malformed object to continueCodeModeApproval: missing `approvalId`, wrong type (e.g. numeric id), missing or non-boolean `approved`, `reason` present but not a string, passing null/undefined, or passing an array. Also occurs when forwarding a deserialized/persisted response (e.g. from JSON in a queue or DB) whose shape changed between serialization points.","commonSituations":"Manually constructing a response object in a custom UI approval handler; storing approval responses in a database and reading back old/renamed field names; deserializing responses over HTTP where types were coerced (approved: \"true\"); upgrading SDK versions where the response schema gained/renamed fields.","solutions":["Log the offending value and verify it has string `approvalId`, boolean `approved`, and optional string `reason`","Ensure you build the response from the interrupt payload's actual `approvalId` rather than a hardcoded/renamed field","Check that the value is not null, undefined, or an array before calling continueCodeModeApproval","Validate the response shape (e.g. with a schema or type guard) before passing it in"],"exampleFix":"// before\nawait continueCodeModeApproval({ approvalId: payload.id, approved: 'yes' });\n// after\nawait continueCodeModeApproval({\n  approvalId: payload.approvalId,\n  approved: true,\n  reason: 'user clicked allow',\n});","handlingStrategy":"type-guard","validationCode":"function isValidApprovalResponse(v: unknown): boolean {\n  return (\n    typeof v === 'object' && v !== null && !Array.isArray(v) &&\n    typeof (v as any).approvalId === 'string' &&\n    typeof (v as any).approved === 'boolean' &&\n    (!('reason' in v) || (v as any).reason === undefined || typeof (v as any).reason === 'string')\n  );\n}\nif (!isValidApprovalResponse(response)) throw new Error('invalid approval response');","typeGuard":"function isCodeModeApprovalResponse(v: unknown): v is CodeModeApprovalResponse {\n  return (\n    typeof v === 'object' && v !== null && !Array.isArray(v) &&\n    typeof (v as { approvalId?: unknown }).approvalId === 'string' &&\n    typeof (v as { approved?: unknown }).approved === 'boolean' &&\n    (!('reason' in v) || (v as { reason?: unknown }).reason === undefined || typeof (v as { reason?: unknown }).reason === 'string')\n  );\n}","tryCatchPattern":"import { CodeModeProtocolError } from '.../errors.js';\ntry {\n  await continueCodeModeApproval(response);\n} catch (error) {\n  if (CodeModeProtocolError.isInstance(error)) {\n    console.error('Malformed approval response:', response);\n    return; // reject or re-prompt the user\n  }\n  throw error;\n}","preventionTips":["Always construct the response from the interrupt payload's approvalId field","Never forward deserialized values without checking shape","Add a schema/unit test for your approval-response builder","Coerce UI inputs to booleans/strings explicitly before assembling the response"],"tags":["code-mode","protocol","schema-validation-failed","approval-flow"],"backgroundTag":"schema-validation-failed","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}