{"record":{"id":"a442031f2c055e6b","repo":"vercel/ai","slug":"you-can-t-modify-the-string-key-field-of-the","errorCode":null,"errorMessage":"You can't modify the \"${String(key)}\" field of the AI state because it's not an object.","messagePattern":"You can't modify the \"(.+?)\" field of the AI state because it's not an object\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/rsc/src/ai-state.tsx","lineNumber":149,"sourceCode":"  );\n\n  if (store.sealed) {\n    throw new Error(\n      \"`getMutableAIState` must be called before returning from an AI Action. Please move it to the top level of the Action's function body.\",\n    );\n  }\n\n  if (!store.mutationDeltaPromise) {\n    const { promise, resolve } = createResolvablePromise();\n    store.mutationDeltaPromise = promise;\n    store.mutationDeltaResolve = resolve;\n  }\n\n  function doUpdate(newState: NewStateOrUpdater, done: boolean) {\n    if (args.length > 0) {\n      if (typeof store.currentState !== 'object') {\n        const key = args[0];\n        throw new Error(\n          `You can't modify the \"${String(\n            key,\n          )}\" field of the AI state because it's not an object.`,\n        );\n      }\n    }\n\n    if (isFunction(newState)) {\n      if (args.length > 0) {\n        store.currentState[args[0]] = newState(store.currentState[args[0]]);\n      } else {\n        store.currentState = newState(store.currentState);\n      }\n    } else {\n      if (args.length > 0) {\n        store.currentState[args[0]] = newState;\n      } else {\n        store.currentState = newState;","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/rsc/src/ai-state.tsx#L131-L167","documentation":"Inside getMutableAIState, doUpdate validates keyed mutations: when a key argument was supplied, the current AI state must be an object to allow updating that field. If the state is a non-object (primitive, null, etc.), mutating a named field is impossible, so the library throws naming the key.","triggerScenarios":"Calling getMutableAIState('key') and then .update(...) (or done with a value) when the stored AI state is not an object — e.g. state initialized to a scalar/null or overwritten with a primitive earlier in the action.","commonSituations":"Scalar initial AI state with keyed mutable access; a previous update replaced the whole state with a primitive; mismatch between assumed and actual state shape across actions.","solutions":["Initialize/keep the AI state as an object so keyed updates are valid.","Call getMutableAIState() without a key and replace the entire (non-object) state instead of mutating a field.","Normalize the state first: update with a full object wrapper before performing keyed updates.","Audit all actions for places that set the state to a non-object value."],"exampleFix":"// before\n// state: \"raw-string\"\nconst state = getMutableAIState('count');\nstate.update({ count: 1 }); // throws\n\n// after\nconst state = getMutableAIState();\nstate.update({ count: 1 }); // replace whole state with an object","handlingStrategy":"validation","validationCode":"const state = getAIState();\nif (typeof state !== 'object' || state === null) {\n  // normalize before keyed mutation\n  setAIState({});\n}","typeGuard":"function canKeyedUpdate(s: unknown): s is Record<string, unknown> {\n  return typeof s === 'object' && s !== null;\n}","tryCatchPattern":"try {\n  const state = getMutableAIState('count');\n  state.update({ count: next });\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"of the AI state because it's not an object\")) {\n    const mutable = getMutableAIState();\n    mutable.update({ count: next }); // replace whole state with an object\n  } else throw e;\n}","preventionTips":["Guarantee the initial AI state is an object in the page's AI provider setup.","Avoid full-state updates that assign primitives; always write object shapes.","Add a schema validation step for AI state at action entry (e.g. zod object schema)."],"tags":["rsc","ai-state","state-shape","mutation"],"backgroundTag":"ai-state-not-an-object","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}