{"record":{"id":"ee7723b1c082fee5","repo":"vercel/ai","slug":"cline-only-text-user-message-parts-are-supported","errorCode":null,"errorMessage":"cline: only text user-message parts are supported; got '${part.type}'.","messagePattern":"cline: only text user-message parts are supported; got '(.+?)'\\.","errorType":"exception","errorClass":"HarnessCapabilityUnsupportedError","httpStatus":null,"severity":"error","filePath":"packages/harness-cline/src/cline-utils.ts","lineNumber":33,"sourceCode":"/**\n * Extract a single user text string from a `HarnessV1Prompt`. The Cline\n * runtime's `run`/`continue` accept a plain string; multimodal user content\n * is not supported in this foundational version.\n */\nexport function extractUserText(prompt: HarnessV1Prompt): string {\n  if (typeof prompt === 'string') {\n    return prompt;\n  }\n\n  const { content } = prompt;\n  if (typeof content === 'string') {\n    return content;\n  }\n\n  const parts: string[] = [];\n  for (const part of content) {\n    if (part.type !== 'text') {\n      throw new HarnessCapabilityUnsupportedError({\n        message: `cline: only text user-message parts are supported; got '${part.type}'.`,\n        harnessId: HARNESS_ID,\n      });\n    }\n    parts.push(part.text);\n  }\n  return parts.join('\\n\\n');\n}\n\nexport function getErrorText(error: unknown): string {\n  return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * Coerce an arbitrary tool output into a JSON-safe value for a `tool-result`\n * stream part. Strings and JSON-serializable objects pass through; anything\n * that can't survive `JSON.stringify` round-tripping (functions, cycles) is\n * stringified. `undefined` becomes `null` — the runtime schema deliberately","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness-cline/src/cline-utils.ts#L15-L51","documentation":"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.","triggerScenarios":"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.","commonSituations":"Multimodal chat apps piping image attachments into every harness uniformly; forwarding UI messages with attachments without filtering parts per harness capability.","solutions":["Send user messages as plain strings or content arrays containing only text parts.","Filter or convert non-text parts (e.g. describe images as text) before calling the Cline session.","Route multimodal messages to a harness that supports image/file parts."],"exampleFix":"// before\nawait session.send([{ type: 'text', text: 'review this' }, { type: 'image', image }]);\n// after\nawait session.send([{ type: 'text', text: 'review this' }]); // image sent via other channel","handlingStrategy":"type-guard","validationCode":"const hasOnlyText = msg.content.every(p => p.type === 'text');\nif (!hasOnlyText) throw new Error('cline harness supports text parts only');","typeGuard":"function isTextOnlyParts(parts) {\n  return parts.every(p => p.type === 'text');\n}","tryCatchPattern":"try {\n  await session.send(message);\n} catch (e) {\n  if (HarnessCapabilityUnsupportedError.isInstance?.(e) || /only text user-message parts/.test(String(e?.message))) {\n    // strip/convert non-text parts and resend\n  } else throw e;\n}","preventionTips":["Filter message parts per harness capability before sending","Convert images/files to textual descriptions for cline","Centralize message preprocessing so all cline calls share it"],"tags":["harness-cline","multimodal","unsupported-capability","message-parts"],"backgroundTag":"unsupported-capability","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}