vercel/ai · warning

[WorkflowChatTransport] Negative initialStartIndex is…

Error message

[WorkflowChatTransport] Negative initialStartIndex is configured (${explicitStartIndex}) but the reconnection endpoint did not return a valid "x-workflow-stream-tail-index" header. Retries will replay the stream from the beginning. See: https://workflow.dev/docs/ai/resumable-streams#resuming-from-the-end-of-the-stream

What it means

A negative initialStartIndex means 'resume N chunks from the end of the stream', which requires the reconnection endpoint to report the total chunk count via the 'x-workflow-stream-tail-index' header. When that header is missing or unparseable, the transport cannot compute the offset and warns that retries will replay the whole stream from the beginning instead.

Solutions

  1. Make the reconnection endpoint return the 'x-workflow-stream-tail-index' header with the last chunk index.
  2. Check that no proxy/middleware strips the custom header from reconnection responses.
  3. Use a non-negative initialStartIndex (absolute chunk position) instead of relative-from-end semantics.
  4. Accept full replay on retries if streams are idempotent for your app.

Example fix

// server: reconnection endpoint
res.setHeader('x-workflow-stream-tail-index', String(lastChunkIndex));
Defensive patterns

Strategy: validation

Validate before calling

// client-side preflight
const res = await fetch(reconnectUrl, { method: 'HEAD' });
if (initialStartIndex < 0 && !res.headers.get('x-workflow-stream-tail-index')) {
  console.warn('Reconnect endpoint lacks tail-index header; full replay will occur.');
}

Prevention

When it happens

Trigger: Configuring WorkflowChatTransport with a negative initialStartIndex while the reconnect endpoint's response lacks a valid numeric 'x-workflow-stream-tail-index' header (header absent, non-numeric, or NaN).

Common situations: Custom reconnection endpoints that don't implement the tail-index header; proxies stripping custom headers; older server versions predating the header.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/13fdc94cd084906b. Report an issue: GitHub.

Appendix: source

Thrown at packages/workflow/src/workflow-chat-transport.ts:481

      if (useExplicitStartIndex && explicitStartIndex > 0) {
        // Positive startIndex: the first request starts at this absolute
        // position, so set chunkIndex to match so subsequent retries
        // resume from (explicitStartIndex + chunks received).
        chunkIndex = explicitStartIndex;
      } else if (useExplicitStartIndex && explicitStartIndex < 0) {
        const tailIndexHeader = response.headers.get(
          'x-workflow-stream-tail-index',
        );
        const tailIndex =
          tailIndexHeader !== null ? parseInt(tailIndexHeader, 10) : NaN;

        if (!Number.isNaN(tailIndex)) {
          // Resolve: e.g. tailIndex=499, startIndex=-20 → 500 + (-20) = 480
          chunkIndex = Math.max(0, tailIndex + 1 + explicitStartIndex);
        } else {
          // Header missing or unparseable — fall back to replaying from the
          // beginning so retries don't resume from a wrong position.
          console.warn(
            '[WorkflowChatTransport] Negative initialStartIndex is configured ' +
              `(${explicitStartIndex}) but the reconnection endpoint did not ` +
              'return a valid "x-workflow-stream-tail-index" header. Retries ' +
              'will replay the stream from the beginning. See: ' +
              'https://workflow.dev/docs/ai/resumable-streams#resuming-from-the-end-of-the-stream',
          );
          replayFromStart = true;
        }
      }
      useExplicitStartIndex = false;

      try {
        const chunkStream = parseJsonEventStream({
          stream: response.body,
          schema: uiMessageChunkSchema,
        });
        for await (const chunk of createAsyncIterableStream(chunkStream)) {
          if (!chunk.success) {

View on GitHub (pinned to 69428b1f8b)