vercel/ai · error · HarnessCapabilityUnsupportedError

The claude-code harness does not yet support user message pa

Error message

The claude-code harness does not yet support user message parts of type '${part.type}'. Pass a string or a user message whose content contains only text parts.

What it means

When sending a prompt to the claude-code harness, only plain strings or user messages whose content is exclusively text parts are supported, because the harness forwards prompts to the Claude Code CLI as text commands. Any other part type (e.g. images, files, tool results) raises HarnessCapabilityUnsupportedError with this message — the harness simply lacks the capability, not just this implementation branch.

Source

Thrown at packages/harness-claude-code/src/claude-code-harness.ts:2098

    },
  };
}

/*
 * Reduce a `HarnessV1Prompt` to the plain user text the bridge forwards
 * to the Claude SDK. File and image parts on the message are not yet
 * supported by the underlying runtime — throw rather than silently drop
 * them so callers learn about the gap instead of seeing mysteriously
 * truncated prompts.
 */
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({
        harnessId: 'claude-code',
        message: `The claude-code harness does not yet support user message parts of type '${part.type}'. Pass a string or a user message whose content contains only text parts.`,
      });
    }
    parts.push(part.text);
  }
  return parts.join('\n\n');
}

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Pass a plain string prompt instead of a structured message
  2. Flatten the message content to text-only parts before sending; convert or drop non-text parts explicitly
  3. Route multimodal prompts to a harness/provider that supports them, or use the claude-code harness's file/attachment options if available instead of inline parts
  4. Add pre-send validation in your app that rejects non-text parts for this harness

Example fix

// before
await session.prompt({
  role: 'user',
  content: [
    { type: 'text', text: 'Describe this:' },
    { type: 'image', image: dataUrl } // unsupported
  ]
});

// after
await session.prompt('Describe this:'); // string or text-only parts only
Defensive patterns

Strategy: validation

Validate before calling

function assertTextOnlyPrompt(prompt) {
  const content = typeof prompt === 'string' ? prompt : prompt.content;
  if (typeof content === 'string') return content;
  for (const part of content) {
    if (part.type !== 'text') {
      throw new Error(`Unsupported prompt part type for claude-code: ${part.type}`);
    }
  }
  return content.map(p => p.text).join('\n');
}

Type guard

function isTextOnlyPrompt(prompt: unknown): prompt is string | { role: 'user'; content: string | Array<{ type: 'text'; text: string }> } {
  if (typeof prompt === 'string') return true;
  const p = prompt as { content?: unknown };
  if (typeof p?.content === 'string') return true;
  return Array.isArray(p?.content) && p.content.every((part: any) => part.type === 'text');
}

Try / catch

try {
  await session.prompt(message);
} catch (err) {
  if (err?.name === 'HarnessCapabilityUnsupportedError' && err.message.includes('user message parts of type')) {
    // fall back to text-only extraction or a multimodal-capable harness
  }
  throw err;
}

Prevention

When it happens

Trigger: Passing a prompt object whose `content` array contains a part with type other than 'text' (image, file, tool-call, etc.) to the session's prompt/send API; building multimodal messages for a harness that only accepts text.

Common situations: Reusing chat-completion-style message arrays (with image parts) across providers and feeding them to the claude-code harness; attaching screenshots or documents to a prompt; a code path generic over HarnessV1 prompts that doesn't restrict content for claude-code.

Related errors


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