mastra-ai/mastra · error · Error

Unhandled toolInvocation.state: ${String(part.toolInvocation

Error message

Unhandled toolInvocation.state: ${String(part.toolInvocation.state)}

What it means

Plain Error thrown by toUIPart in the AIV6 adapter when converting a tool part whose toolInvocation.state is not one of the handled states (e.g. 'partial-call', 'call', 'result', or an unexpected value like undefined). The adapter enumerates known invocation states and hits the default branch for anything else, indicating the message contains a toolInvocation in an unrecognized or corrupted state.

Source

Thrown at packages/core/src/agent/message-list/adapters/AIV6Adapter.ts:681

                'output-available',
                getDisplayTransform(part.providerMetadata, 'error', part.toolInvocation.result),
              ),
            },
            {
              preliminary: part.preliminary,
              approval:
                part.toolInvocation.approval?.approved === true
                  ? {
                      id: part.toolInvocation.approval.id,
                      approved: true,
                      reason: part.toolInvocation.approval.reason,
                    }
                  : undefined,
            },
          ) as AIV6Type.UIMessage['parts'][number];

        default:
          throw new Error(`Unhandled toolInvocation.state: ${String(part.toolInvocation.state)}`);
      }
    }

    if (part.type === 'source-document') {
      return withOptionalFields(
        {
          type: 'source-document',
          sourceId: part.sourceId,
          mediaType: part.mediaType,
          title: part.title,
        },
        {
          filename: part.filename,
          providerMetadata: part.providerMetadata,
        },
      ) as AIV6Type.UIMessage['parts'][number];
    }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Ensure every toolInvocation in the message has a valid state: 'partial-call', 'call', or 'result'.
  2. Check that message-producing and message-consuming sides use the same AI SDK v6 type versions; regenerate/normalize old persisted messages.
  3. Inspect String(part.toolInvocation.state) in the thrown message to identify the unexpected value and fix the producer.
  4. If a legitimately new state variant, upgrade @mastra/core to a version that handles it.

Example fix

// before
{ type: 'tool-invocation', toolInvocation: { toolCallId: 't1', toolName: 'weather' } } // no state

// after
{ type: 'tool-invocation', toolInvocation: { toolCallId: 't1', toolName: 'weather', state: 'result', result: {...} } }
Defensive patterns

Strategy: type-guard

Validate before calling

const VALID_STATES = ['partial-call', 'call', 'result'] as const;
function assertValidToolInvocation(part: any): void {
  if (part?.type === 'tool-invocation' && !VALID_STATES.includes(part.toolInvocation?.state)) {
    throw new Error(`Unexpected toolInvocation.state: ${String(part.toolInvocation?.state)}`);
  }
}

Type guard

function hasKnownInvocationState(p: any): p is { type: 'tool-invocation'; toolInvocation: { state: 'partial-call' | 'call' | 'result' } } {
  return p?.type === 'tool-invocation' && ['partial-call', 'call', 'result'].includes(p.toolInvocation?.state);
}

Try / catch

try {
  const uiMessage = toUIMessage(v6Message);
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Unhandled toolInvocation.state')) {
    logger.warn('Skipping message with unknown toolInvocation state:', e.message);
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: Converting an AIV6 message containing a tool-invocation part whose state is undefined/missing, misspelled (e.g. 'complete' instead of 'result'), from a newer/older AI SDK version with an added state variant, or a hand-crafted toolInvocation object without a state field.

Common situations: Mixing message versions after upgrading AI SDK (new state enum values not yet handled by the adapter); manually constructing UI messages; persisted messages whose toolInvocation was partially deserialized; streaming interrupted leaving state unset.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/dedce679fb080c6d. Report an issue: GitHub.