vercel/ai · error · HarnessCapabilityUnsupportedError
The ${harnessId} ACP harness supports only portable text pro
Error message
The ${harnessId} ACP harness supports only portable text prompts and does not support image content. Pass a string or a user message whose content contains only text parts. What it means
convertHarnessPromptToACPTextBlocks rejects prompts containing image content parts. The ACP v1 harness only supports portable text prompts, so any prompt whose message content includes an image part causes this unsupportedPromptContent error before the prompt is sent to the agent.
Source
Thrown at packages/harness-acp/src/v1/acp-v1-prompt.ts:35
}: {
prompt: HarnessV1Prompt;
harnessId: string;
}): ACPTextContentBlock[] {
if (typeof prompt === 'string') {
return [{ type: 'text', text: prompt }];
}
if (typeof prompt.content === 'string') {
return [{ type: 'text', text: prompt.content }];
}
const content: ACPTextContentBlock[] = [];
for (const part of prompt.content) {
if (part.type === 'text') {
content.push({ type: 'text', text: part.text });
continue;
}
if (part.type === 'image') {
throw unsupportedPromptContent({
harnessId,
category: 'image content',
});
}
if (part.type === 'file') {
const mediaCategory = part.mediaType.toLowerCase().split('/', 1)[0];
if (mediaCategory === 'image') {
throw unsupportedPromptContent({
harnessId,
category: 'image content',
});
}
if (mediaCategory === 'audio') {
throw unsupportedPromptContent({
harnessId,
category: 'audio content',
});
}View on GitHub (pinned to 69428b1f8b)
Solutions
- Send a plain string prompt or a user message whose content contains only text parts.
- Describe or OCR the image into a text part before prompting.
- Filter or reject image parts in your UI/adapter layer before they reach the harness.
Example fix
// before
await prompt({ content: [{ type: 'text', text: 'What is this?' }, { type: 'image', image: buf }] });
// after
await prompt({ content: [{ type: 'text', text: 'What is this? (describe the screenshot in words)' }] }); Defensive patterns
Strategy: validation
Validate before calling
const hasImage = typeof prompt !== 'string' &&
typeof prompt.content !== 'string' &&
prompt.content.some(p => p.type === 'image');
if (hasImage) throw new Error('ACP v1 harness prompts must contain only text parts'); Type guard
function isTextOnlyPrompt(p: unknown): boolean {
if (typeof p === 'string') return true;
const q = p as { content?: unknown };
if (typeof q.content === 'string') return true;
return Array.isArray(q.content) &&
q.content.every((part: any) => part?.type === 'text');
} Try / catch
try {
await session.prompt(msg);
} catch (e) {
if (String(e?.message).includes('does not support image content')) {
await session.prompt(toTextOnly(msg));
} else throw e;
} Prevention
- Sanitize message content to text-only parts before any ACP harness prompt
- Convert images to textual descriptions in the adapter layer
- Hide image upload affordances when the backend is an ACP harness
When it happens
Trigger: Prompting an ACP v1 harness session with a user message whose content array contains a part with type: 'image', or any non-string prompt that resolves to image parts.
Common situations: Reusing a multimodal chat pipeline (screenshots, image uploads) against an ACP coding-agent harness; passing through user attachments unfiltered.
Related errors
- The ${harnessId} ACP harness supports only portable text pro
- The ${harnessId} ACP harness supports only portable text pro
- DeepSeek image media type ${resolvedMediaType}
- The ${harnessId} ACP harness supports only portable text pro
- The ${model.provider} model "${model.modelId}" does not supp
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/d8cbe4ec39e35d2c.
Report an issue: GitHub.