MissingToolResultsError fires when you send messages back to the model and some tool call in the history has no matching tool result. The model API rejects dangling calls.

Typical trigger: you persist chat messages, reload them, and forget that a tool call from the previous turn never got its result recorded.

import { MissingToolResultsError, streamText } from 'ai';

try {
  await streamText({ model, messages });
} catch (error) {
  if (MissingToolResultsError.isInstance(error)) {
    // find tool calls in messages with no corresponding tool result part
  }
}

What to know:
1. Every tool-call part needs a tool-result part before the messages go back to the model. This is a provider API requirement, not an SDK quirk.
2. The common cause is client-side tools: the model called a client tool, the UI never called addToolOutput, and the next sendMessage ships the dangling call.
3. Fix at the source: when loading persisted messages, filter or repair incomplete tool rounds before calling streamText. Dropping the dangling assistant turn is usually right.
4. Related errors: InvalidToolApprovalError and InvalidToolApprovalSignatureError fire on the approval path when approval metadata is malformed or its signature does not verify.
5. In useChat, sendAutomaticallyWhen with lastAssistantMessageIsCompleteWithToolCalls keeps rounds complete automatically. If you manage submission manually, you own this invariant.
6. When debugging, print the message parts and look for tool parts stuck in 'input-available' or 'call' state with no result. That is your dangling call.