mastra-ai/mastra · error

UI Messages require a data property when using data- prefixe

Error message

UI Messages require a data property when using data- prefixed chunks 
 ${JSON.stringify(part)}

What it means

When converting a full stream to a UI message stream, a data-prefixed chunk's output (part.output) is recognized as a data chunk but lacks a `data` property. The AI SDK UI message format requires every data- chunk to carry its payload under `data`, so the converter throws with the offending part serialized.

Source

Thrown at client-sdks/ai-sdk/src/helpers.ts:774

          type: 'tool-agent',
          toolCallId: part.toolCallId,
          payload: part.output,
        };
      } else if (part.output.from === 'WORKFLOW') {
        return {
          type: 'tool-workflow',
          toolCallId: part.toolCallId,
          payload: part.output,
        };
      } else if (part.output.from === 'NETWORK') {
        return {
          type: 'tool-network',
          toolCallId: part.toolCallId,
          payload: part.output,
        };
      } else if (isDataChunkType(part.output)) {
        if (!('data' in part.output)) {
          throw new Error(
            `UI Messages require a data property when using data- prefixed chunks \n ${JSON.stringify(part)}`,
          );
        }
        const { type, data, id } = part.output;
        return { type, data, ...(id !== undefined && { id }) } as InferUIMessageChunk<UI_MESSAGE>;
      }
      return;
    }

    case 'tool-error': {
      return {
        type: 'tool-output-error',
        toolCallId: part.toolCallId,
        errorText: onError(part.error),
        ...(part.providerExecuted != null ? { providerExecuted: part.providerExecuted } : {}),
        ...(part.dynamic != null ? { dynamic: part.dynamic } : {}),
      };
    }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Rename the payload key on the chunk output to `data`
  2. Ensure custom data chunks are shaped {type:'data-xxx', data:<payload>} (optional id allowed)
  3. If using tool-network chunks, put the payload in part.output.data rather than a custom field
  4. Check the AI SDK version's UIMessageChunk contract for data- chunks

Example fix

// before
yield { type: 'data-weather', forecast: forecastData }
// after
yield { type: 'data-weather', data: forecastData }
Defensive patterns

Strategy: validation

Validate before calling

function assertDataChunk(out: { type: string } & Record<string, unknown>) {
  if (out.type?.startsWith('data-') && !('data' in out)) {
    throw new Error(`data- chunk ${out.type} missing required "data" property`);
  }
}

Type guard

function hasDataProp<T extends { type: string }>(c: T): c is T & { data: unknown } {
  return 'data' in c;
}

Try / catch

try {
  for await (const chunk of result.toUIMessageStream()) {
    ui.messages.push(chunk);
  }
} catch (e) {
  if (String(e.message).startsWith('UI Messages require a data property')) {
    console.error('Malformed data chunk from server:', e.message);
  }
}

Prevention

When it happens

Trigger: A tool-network or custom data chunk whose `output` object matches isDataChunkType (type starts with 'data-') but has fields like {type:'data-foo', value:...} instead of {type:'data-foo', data:...}.

Common situations: Custom tool writers emitting tool-network chunks with ad-hoc payload shapes, migration from older Mastra/AI SDK chunk formats where the payload lived under a different key, or typos like 'dat' or 'payload'.

Related errors


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