vercel/ai · error · HarnessCapabilityUnsupportedError

cline: only text user-message parts are supported; got

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.

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.

Appendix: 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)