AI_UIMessageStreamError — UI 메시지 스트림 에러

AI_UIMessageStreamError — UI 메시지 스트림 에러

UI 메시지 스트림이 에러를 보고하거나 잘못된·순서가 어긋난 청크(chunk)를 포함할 때 발생하는 에러를 다뤄요. 커스텀 트랜스포트로 채팅 스트림을 직접 다룰 때 자주 마주치게 되는 에러예요.

출처: 문서

본문

이 에러는 UI 메시지 스트림이 에러를 보고하거나 잘못된·순서가 어긋난 청크를 포함할 때 발생해요.

흔한 원인:

  • 완성(completion) 데이터 스트림에서 error 청크를 받음
  • 앞선 text-start 청크 없이 text-delta 청크를 받음
  • 앞선 text-start 청크 없이 text-end 청크를 받음
  • 앞선 reasoning-start 청크 없이 reasoning-delta 청크를 받음
  • 앞선 reasoning-start 청크 없이 reasoning-end 청크를 받음
  • 앞선 tool-input-start 청크 없이 tool-input-delta 청크를 받음
  • 존재하지 않는 도구 호출(tool invocation)에 접근하려 함

이 에러는 보통 업스트림 요청이 토큰이 스트리밍되기 전에 실패하고, 커스텀 트랜스포트가 적절한 start 청크 없이 인라인 에러 메시지를 UI 스트림에 쓰려고 할 때 표면화돼요.

속성 (Properties)

  • chunkType: 에러를 일으킨 청크의 타입 (예: text-delta, reasoning-end, tool-input-delta)
  • chunkId: 실패한 청크에 연결된 ID (part ID 또는 toolCallId). 완성 error 청크처럼 ID가 없는 청크의 경우 빈 문자열이에요.
  • message: 무엇이 잘못됐는지에 대한 세부 내용이 담긴 에러 메시지

이 에러 확인하기

에러가 AI_UIMessageStreamError의 인스턴스인지 확인하려면 이렇게 해요:

import { UIMessageStreamError } from 'ai';

if (UIMessageStreamError.isInstance(error)) {
  console.log('Chunk type:', error.chunkType);
  console.log('Chunk ID:', error.chunkId);
  // Handle the error
}

흔한 해결 방법

  1. 청크 순서를 올바르게 유지하세요: 같은 ID에 대해 *-delta나 *-end 청크를 보내기 전에 항상 *-start 청크를 먼저 보내야 해요:

    // 올바른 순서
    writer.write({ type: 'text-start', id: 'my-text' });
    writer.write({ type: 'text-delta', id: 'my-text', delta: 'Hello' });
    writer.write({ type: 'text-end', id: 'my-text' });
    
  2. ID가 일치하는지 확인하세요: *-delta와 *-end 청크에서 사용한 id가 해당 *-start 청크의 id와 일치해야 해요.

  3. 에러 경로를 올바르게 처리하세요: 커스텀 트랜스포트에서 에러 메시지를 쓸 때는 start/delta/end 전체 시퀀스를 내보내는지 확인하세요:

    // 커스텀 트랜스포트에서 에러 처리 시
    writer.write({ type: 'text-start', id: errorId });
    writer.write({
      type: 'text-delta',
      id: errorId,
      delta: 'Request failed...',
    });
    writer.write({ type: 'text-end', id: errorId });
    
  4. 스트림 프로듀서 로직을 점검하세요: 특히 동시 작업이나 병합된 스트림을 다룰 때 청크가 올바른 순서로 전송되도록 스트리밍 구현을 검토해보세요.

더 알아보기 (Learn more)