vercel/ai · error · Error

.append(): The value is not a string. Received: ${typeof val

Error message

.append(): The value is not a string. Received: ${typeof value}

What it means

append() validates its argument must be a string since it streams incremental text chunks. Passing a non-string value (number, object, etc.) throws this error reporting the received typeof.

Source

Thrown at packages/rsc/src/streamable-value/create-streamable-value.ts:234

      resolvePrevious(createWrapped());

      warnUnclosedStream();

      return streamable;
    },
    append(value: T) {
      assertStream('.append()');

      if (
        typeof currentValue !== 'string' &&
        typeof currentValue !== 'undefined'
      ) {
        throw new Error(
          `.append(): The current value is not a string. Received: ${typeof currentValue}`,
        );
      }
      if (typeof value !== 'string') {
        throw new Error(
          `.append(): The value is not a string. Received: ${typeof value}`,
        );
      }

      const resolvePrevious = resolvable.resolve;
      resolvable = createResolvablePromise();

      if (typeof currentValue === 'string') {
        currentPatchValue = [0, value];
        (currentValue as string) = currentValue + value;
      } else {
        currentPatchValue = undefined;
        currentValue = value;
      }

      currentPromise = resolvable.promise;
      resolvePrevious(createWrapped());

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Coerce the chunk to a string before appending (String(chunk) or chunk.toString())
  2. Use update() if you need to set non-string values
  3. Add runtime validation on streamed data before appending
  4. Fix TypeScript types so append is only called with string values

Example fix

// before
streamable.append(chunk); // chunk: unknown
// after
if (typeof chunk === 'string') streamable.append(chunk);
Defensive patterns

Strategy: validation

Validate before calling

function appendText(streamable, chunk) {
  if (typeof chunk !== 'string') {
    throw new TypeError('append expects string chunks, got: ' + typeof chunk);
  }
  streamable.append(chunk);
}

Type guard

function isStringChunk(chunk) {
  return typeof chunk === 'string';
}

Try / catch

try {
  streamable.append(chunk);
} catch (e) {
  if (!/The value is not a string/.test(String(e.message))) throw e;
  streamable.append(String(chunk));
}

Prevention

When it happens

Trigger: Calling streamable.append(123), .append(someObject), .append(null), or .append(undefined) on a streamable value.

Common situations: Passing non-string LLM token deltas (e.g. parsed objects) to append; assuming append accepts arbitrary values like update does; TS types bypassed with any or untyped data from an API.

Related errors


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