shadcn-ui/ui · error

get() cannot materialize a continuation turn without a live

Error message

get() cannot materialize a continuation turn without a live transcript.

What it means

chat.get(count) refuses to return more turns than the materialized (non-deferred) prefix. If the transcript contains a deferred continuation turn (resolve set) and count would include it, get() throws, because materializing a continuation requires a live transcript replay rather than a static snapshot.

Source

Thrown at packages/helpers/src/core/chat.ts:733

      return api
    },

    get(count) {
      const deferredIndex = turns.findIndex(
        (turn) => turn.resolve !== undefined
      )
      const limit = deferredIndex === -1 ? turns.length : deferredIndex

      if (count === undefined) {
        count = limit
      }

      if (!Number.isInteger(count) || count < 0) {
        throw new RangeError("count must be a non-negative integer.")
      }

      if (deferredIndex !== -1 && count > deferredIndex) {
        throw new Error(
          "get() cannot materialize a continuation turn without a live transcript."
        )
      }

      return turns
        .slice(0, count)
        .map((turn) => cloneValue(turn.message as MESSAGE))
    },

    next(messages) {
      const turn = findNextUserTurn(messages)

      return turn?.message ? cloneValue(turn.message) : null
    },

    transport(
      transportOptions: ChatTransportOptions<
        MESSAGE,

View on GitHub (pinned to efac598707)

Solutions

  1. Call get() with no count (it auto-clamps to the deferred boundary) or pass a count at or below the deferred turn index.
  2. Drive continuation turns through the transport (which replays) rather than get().
  3. Before snapshotting, confirm no turn has resolve set.

Example fix

// before
chat.get(3) // throws if turn 2 is a deferred continuation

// after
chat.get()  // auto-stops at the deferred boundary
// or chat.get(2)
Defensive patterns

Strategy: validation

Validate before calling

// get() with no arg already clamps to the deferred boundary
const messages = chat.get()
// if you must pass a count, ensure it is <= the deferred turn index

Try / catch

try {
  chat.get(n)
} catch (e) {
  if (/continuation turn without a live transcript/.test((e as Error).message)) {
    return chat.get() // fall back to the safe prefix
  }
  throw e
}

Prevention

When it happens

Trigger: Calling chat.get(n) where n exceeds the index of the first deferred turn; snapshotting a chat mid-continuation before the user's approval result is applied.

Common situations: Replay or persistence scenarios; asking for all turns while the chat is paused on an approval-gated continuation.

Related errors


AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12). Data as JSON: /api/errors/ec6d6be46dca965e. Report an issue: GitHub.