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 embedded resource content with media type ${JSON.stringify(part.mediaType)}. Pass a string or a user message whose content contains only text parts.

What it means

Fallback for non-image, non-audio file parts: convertHarnessPromptToACPTextBlocks rejects any embedded resource (file) content whose media type is not explicitly handled, reporting the exact media type in the message. ACP v1 prompts may contain text blocks only.

Source

Thrown at packages/harness-acp/src/v1/acp-v1-prompt.ts:54

        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',
        });
      }
      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,
}: {

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Extract the relevant content into a text part (e.g. paste the PDF text) instead of attaching the file.
  2. Provide file contents via the agent's own file-system/workspace tools rather than prompt parts.
  3. Pre-validate and strip non-text parts from prompts sent to ACP v1 harnesses.

Example fix

// before
content: [{ type: 'file', mediaType: 'application/pdf', data }]
// after
content: [{ type: 'text', text: pdfExtractedText }]
Defensive patterns

Strategy: validation

Validate before calling

const hasNonTextFile = typeof prompt !== 'string' &&
  typeof prompt.content !== 'string' &&
  prompt.content.some(p => p.type === 'file');
if (hasNonTextFile) throw new Error('ACP v1 harness prompts cannot include file/resource parts; inline the content as text');

Type guard

function hasFileParts(prompt: unknown): boolean {
  const p = prompt as { content?: unknown };
  return Array.isArray(p?.content) &&
    (p.content as any[]).some(part => part?.type === 'file');
}

Try / catch

try {
  await session.prompt(msg);
} catch (e) {
  if (String(e?.message).includes('embedded resource content')) {
    await session.prompt(inlineFilesAsText(msg));
  } else throw e;
}

Prevention

When it happens

Trigger: Prompting an ACP v1 harness with a file part of any other media type (e.g. application/pdf, video/mp4, text/csv as a file part).

Common situations: Attaching PDFs, videos, or data files to prompts and assuming the harness will forward them like a full multimodal provider.

Related errors


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