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 content parts of type ${JSON.stringify((part as { readonly type?: unknown }).type)}. Pass a string or a user message whose content contains only text parts. What it means
Final catch-all in convertHarnessPromptToACPTextBlocks: any content part whose type is not 'text', 'image', or 'file' triggers unsupportedPromptContent with the unknown part type embedded in the message. The ACP v1 harness only accepts text content parts.
Source
Thrown at packages/harness-acp/src/v1/acp-v1-prompt.ts:59
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',
});
}
throw unsupportedPromptContent({
harnessId,
category: `embedded resource content with media type ${JSON.stringify(part.mediaType)}`,
});
}
throw unsupportedPromptContent({
harnessId,
category: `content parts of type ${JSON.stringify(
(part as { readonly type?: unknown }).type,
)}`,
});
}
return content;
}
export function prependACPInstructionGuidance({
prompt,
instructions,
}: {
prompt: ReadonlyArray<ACPTextContentBlock>;
instructions: string | undefined;
}): ACPTextContentBlock[] {
const hasInstructions = instructions != null && instructions.length > 0;
if (!hasInstructions) return [...prompt];View on GitHub (pinned to 69428b1f8b)
Solutions
- Ensure prompt.content contains only text parts before calling the harness.
- Upgrade or align the SDK packages so part types match what HarnessV1 defines and ACP supports.
- Add a mapper that converts or drops non-text parts prior to prompting.
Example fix
// before
content: [...msg.content] // may include { type: 'tool-result', ... }
// after
content: msg.content.filter(p => p.type === 'text') Defensive patterns
Strategy: validation
Validate before calling
const unknown = typeof prompt !== 'string' &&
Array.isArray(prompt.content) &&
prompt.content.filter(p => p.type !== 'text' && p.type !== 'image' && p.type !== 'file');
if (unknown.length) throw new Error(`Unknown content part types: ${unknown.map(p => p.type).join(', ')}`); Type guard
function isKnownPart(part: unknown): boolean {
const t = (part as { type?: unknown })?.type;
return t === 'text' || t === 'image' || t === 'file';
} Try / catch
try {
await session.prompt(msg);
} catch (e) {
if (String(e?.message).includes('content parts of type')) {
await session.prompt({ content: msg.content.filter(isKnownPartAndTextOnly) });
} else throw e;
} Prevention
- Keep SDK package versions in sync so part types stay within the known union
- Whitelist part types at the boundary where messages enter the harness
- Log and drop unrecognized parts instead of forwarding them
When it happens
Trigger: Prompting an ACP v1 harness with a content part of an unrecognized/unsupported type (e.g. 'tool-result', 'resource', or a part from a newer SDK version) inside prompt.content.
Common situations: SDK version mismatches introducing new part types; generic message-forwarding code passing arbitrary provider part types straight into the harness prompt.
Related errors
- The ${harnessId} ACP harness supports only portable text pro
- The ${harnessId} ACP harness supports only portable text pro
- The ${harnessId} ACP harness supports only portable text pro
- The ${model.provider} model "${model.modelId}" does not supp
- Invalid argument for parameter requests: requests must not b
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/a04b8470db8556b3.
Report an issue: GitHub.