vercel/ai · error · HarnessCapabilityUnsupportedError

Harness '${input.harness.harnessId}' does not support built-

Error message

Harness '${input.harness.harnessId}' does not support built-in tool filtering controls.

What it means

Built-in tool filtering (activeTools/inactiveTools affecting the harness's built-in tools) is an optional capability. If you supply builtin tool filtering settings for a harness whose harnessId reports neither supportsBuiltinToolFiltering nor supportsBuiltinToolApprovals, a HarnessCapabilityUnsupportedError is thrown.

Source

Thrown at packages/harness/src/agent/internal/tool-filtering.ts:68

  const builtinToolFiltering =
    disabledBuiltinToolNames.length > 0
      ? activeTools != null
        ? {
            mode: 'allow' as const,
            toolNames: builtinToolNames.filter(name =>
              activeTools.includes(name),
            ),
          }
        : { mode: 'deny' as const, toolNames: disabledBuiltinToolNames }
      : undefined;

  if (
    builtinToolFiltering != null &&
    input.harness.supportsBuiltinToolFiltering !== true &&
    input.harness.supportsBuiltinToolApprovals !== true
  ) {
    throw new HarnessCapabilityUnsupportedError({
      message: `Harness '${input.harness.harnessId}' does not support built-in tool filtering controls.`,
      harnessId: input.harness.harnessId,
    });
  }

  return {
    activeUserTools: filterToolSet({
      tools: input.userTools,
      toolNames: activeUserToolNames,
    }),
    ...(builtinToolFiltering != null ? { builtinToolFiltering } : {}),
  };
}

function dedupeToolNames(input: {
  toolNames: ReadonlyArray<string> | undefined;
}): ReadonlyArray<string> | undefined {
  return input.toolNames == null

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Check harness.supportsBuiltinToolFiltering before passing builtin tool filtering options.
  2. Restrict filtering to user-defined tools, or drop the builtinToolFiltering setting for this harness.
  3. Upgrade the harness package to a version whose adapter supports builtin tool filtering.

Example fix

// before
new HarnessAgent({ harness: minimalHarness, builtinToolFiltering: { inactiveTools: ['shell'] } });
// after
if (minimalHarness.supportsBuiltinToolFiltering) {
  new HarnessAgent({ harness: minimalHarness, builtinToolFiltering: { inactiveTools: ['shell'] } });
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (cfg.builtinToolFiltering && !harness.supportsBuiltinToolFiltering && !harness.supportsBuiltinToolApprovals) { delete cfg.builtinToolFiltering; }

Type guard

function supportsBuiltinFiltering(h: Harness): h is Harness & { supportsBuiltinToolFiltering: true } { return h.supportsBuiltinToolFiltering === true || h.supportsBuiltinToolApprovals === true; }

Try / catch

try { createAgent({ harness, builtinToolFiltering }); } catch (e) { if (e instanceof HarnessCapabilityUnsupportedError) { createAgent({ harness }); } else throw e; }

Prevention

When it happens

Trigger: Configuring builtin tool filtering for a harness like one that only exposes agent-level tools; passing builtinToolFiltering while the harness adapter's supportsBuiltinToolFiltering/supportsBuiltinToolApprovals flags are not true.

Common situations: Copying tool-filtering config between different harnesses (e.g. from Claude Code to a minimal harness); using an older harness adapter that predates the capability flags.

Related errors


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