moeru-ai/airi · info

Text reading aborted

Error message

Text reading aborted

What it means

PoppinText.web.vue streams incoming text grapheme-by-grapheme via readGraphemeClusters(text.getReader(), { signal }). When the effect re-runs (new text) or the component tears down, the AbortController aborts and the stream read rejects with Error('Aborted'). The catch recognizes that message and logs this warn: it is the designed cancellation path, not an error — real failures go to console.error in the else branch.

Source

Thrown at packages/stage-ui/src/components/widgets/poppin-text/PoppinText.web.vue:102

  abortController.value = new AbortController()

  try {
    streamTextGeneration += 1
    animatedTargetIds.clear()
    targets.value = []

    for await (const cluster of readGraphemeClusters(text.getReader(), { signal: abortController.value.signal })) {
      targets.value.push({
        id: `stream:${streamTextGeneration}:${targets.value.length}`,
        grapheme: cluster,
      })

      emits('textSplit', cluster)
    }
  }
  catch (error) {
    if (error instanceof Error && error.message === 'Aborted') {
      console.warn('Text reading aborted')
    }
    else {
      console.error('Error reading text:', error)
    }
  }
}, { immediate: true })

const elements = ref<HTMLElement[]>([])
const animatorCleanupFn = shallowRef<() => void>()
const activeAnimator = shallowRef<Animator>()

onMounted(() => {
  animatorCleanupFn.value = props.animator?.(elements.value.slice())
  activeAnimator.value = props.animator
  targets.value.forEach(target => animatedTargetIds.add(target.id))
})

watch([targets, () => props.animator], ([targets, animator]) => {

View on GitHub (pinned to 677329427f)

Solutions

  1. No code fix needed — this is expected cancellation; exclude the known 'Aborted' message from error telemetry
  2. If the warning is noisy, downgrade it to console.debug or drop it entirely since the abort was requested by this component itself
  3. Verify genuine failures are not masked: keep the else branch reporting unexpected errors

Example fix

// before
if (error instanceof Error && error.message === 'Aborted') {
  console.warn('Text reading aborted')
}
else {
  console.error('Error reading text:', error)
}

// after
if (error instanceof Error && error.message === 'Aborted') {
  // expected: we aborted the previous read ourselves
  return
}
console.error('Error reading text:', error)
Defensive patterns

Strategy: try-catch

Type guard

function isAbortError(error: unknown): boolean {
  return error instanceof Error && (error.message === 'Aborted' || error.name === 'AbortError')
}

Try / catch

catch (error) {
  if (isAbortError(error)) {
    return // self-requested cancellation, not an error
  }
  console.error('Error reading text:', error)
}

Prevention

When it happens

Trigger: props.text changes while a previous stream is still being read (rapid LLM token updates), component unmount mid-stream, or any explicit abortController.abort() before the reader finished.

Common situations: Fast consecutive streaming updates replacing each other; navigating away while text animates; a new generation cancelling the previous one.

Related errors


AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18). Data as JSON: /api/errors/0c1fa0e6bdf2cfef. Report an issue: GitHub.