vercel/ai · error · HarnessCapabilityUnsupportedError

cline: only text user-message parts are supported; got '${pa

Error message

cline: only text user-message parts are supported; got '${part.type}'.

What it means

extractUserText converts user message content for the Cline harness but only supports plain text parts. If a user message contains an image, file, or other non-text part, it throws HarnessCapabilityUnsupportedError because the Cline harness cannot represent that part type.

Source

Thrown at packages/harness-cline/src/cline-utils.ts:33

/**
 * Extract a single user text string from a `HarnessV1Prompt`. The Cline
 * runtime's `run`/`continue` accept a plain string; multimodal user content
 * is not supported in this foundational version.
 */
export function extractUserText(prompt: HarnessV1Prompt): string {
  if (typeof prompt === 'string') {
    return prompt;
  }

  const { content } = prompt;
  if (typeof content === 'string') {
    return content;
  }

  const parts: string[] = [];
  for (const part of content) {
    if (part.type !== 'text') {
      throw new HarnessCapabilityUnsupportedError({
        message: `cline: only text user-message parts are supported; got '${part.type}'.`,
        harnessId: HARNESS_ID,
      });
    }
    parts.push(part.text);
  }
  return parts.join('\n\n');
}

export function getErrorText(error: unknown): string {
  return error instanceof Error ? error.message : String(error);
}

/**
 * Coerce an arbitrary tool output into a JSON-safe value for a `tool-result`
 * stream part. Strings and JSON-serializable objects pass through; anything
 * that can't survive `JSON.stringify` round-tripping (functions, cycles) is
 * stringified. `undefined` becomes `null` — the runtime schema deliberately

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Send user messages as plain strings or content arrays containing only text parts.
  2. Filter or convert non-text parts (e.g. describe images as text) before calling the Cline session.
  3. Route multimodal messages to a harness that supports image/file parts.

Example fix

// before
await session.send([{ type: 'text', text: 'review this' }, { type: 'image', image }]);
// after
await session.send([{ type: 'text', text: 'review this' }]); // image sent via other channel
Defensive patterns

Strategy: type-guard

Validate before calling

const hasOnlyText = msg.content.every(p => p.type === 'text');
if (!hasOnlyText) throw new Error('cline harness supports text parts only');

Type guard

function isTextOnlyParts(parts) {
  return parts.every(p => p.type === 'text');
}

Try / catch

try {
  await session.send(message);
} catch (e) {
  if (HarnessCapabilityUnsupportedError.isInstance?.(e) || /only text user-message parts/.test(String(e?.message))) {
    // strip/convert non-text parts and resend
  } else throw e;
}

Prevention

When it happens

Trigger: Sending a user message whose content array includes a part with type other than 'text' (e.g. { type: 'image' }, { type: 'file' }) through a Cline harness session.

Common situations: Multimodal chat apps piping image attachments into every harness uniformly; forwarding UI messages with attachments without filtering parts per harness capability.

Related errors


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