« All posts

Deprecated Accessor Trap in AI SDK v7 Silently Erases Agent Memory

In AI SDK v7, result.response.messages now returns only the final step, silently dropping tool calls from history and crippling multi-turn agent behavior in smaller models.

A benchmark testing multi-turn tool-calling agents kept showing an odd failure: a model would execute a tool call correctly in one turn, then respond with a bare "DONE" when asked to repeat an equivalent edit later, without calling any tool. The initial explanation blamed small-model fragility in multi-turn tasks, but inconsistent follow-up results, including one prompt mitigation crashing a top model's success rate from 100% to 7.5%, pushed the team to inspect the raw message arrays being sent to the model.

The root cause turned out to be a library behavior: in AI SDK v7, result.response.messages silently changed meaning to return only the final step's text in a multi-step tool run, while the accumulated tool calls and results moved to a separate accessor (result.responseMessages or result.steps). This same field had been the documented pattern for capturing full history in v5, so the code still typechecked and ran, just with a different meaning, flagged only by an editor-visible deprecation note invisible to CI. As a result, every multi-turn conversation quietly lost the model's own tool activity, so from the model's perspective there was no prior tool call at all, making "DONE" the only coherent continuation.

A controlled A/B test across 2,160 cells confirmed the mechanism directly: with the buggy history, follow-up success ranged from 5% to 100% depending on the model, but with corrected history every model and configuration hit 100%. Frontier models mask the defect well because they act confidently on the current instruction regardless of context quality, which means the bug can lie dormant until a cheaper, smaller model is swapped in and the failure surfaces as a silent, non-throwing behavior. The recommended fix is a simple audit: dump the actual message array sent on each turn and check whether tool-call and tool-result parts from prior turns are actually present.

» SourceHashnode #8