vercel/ai · error · HarnessBridgeCapabilityUnsupportedError

ACP permission mapping for ${JSON.stringify(permissionMode)}

Error message

ACP permission mapping for ${JSON.stringify(permissionMode)} requires session configuration ${JSON.stringify(target.configId)}, but the agent advertised ${formatChoices({ values: availableConfigIds })}.

What it means

When the permission mode maps to a config-option target, validateTarget looks up the target configId in the agent-advertised sessionConfiguration.configOptions. If no config option with that id exists, the harness throws this unsupported error listing the config option ids the agent actually advertises.

Source

Thrown at packages/harness-acp/src/v1/bridge/permission-mode.ts:106

    if (!availableModeIds.includes(target.modeId)) {
      throw unsupported({
        harnessId,
        message:
          `ACP permission mapping for ${JSON.stringify(permissionMode)} requires session mode ` +
          `${JSON.stringify(target.modeId)}, but the agent advertised ` +
          `${formatChoices({ values: availableModeIds })}.`,
      });
    }
    return;
  }

  const configOption = sessionConfiguration.configOptions?.find(
    option => option.id === target.configId,
  );
  if (configOption == null) {
    const availableConfigIds =
      sessionConfiguration.configOptions?.map(option => option.id) ?? [];
    throw unsupported({
      harnessId,
      message:
        `ACP permission mapping for ${JSON.stringify(permissionMode)} requires session configuration ` +
        `${JSON.stringify(target.configId)}, but the agent advertised ` +
        `${formatChoices({ values: availableConfigIds })}.`,
    });
  }
  if (configOption.type === 'boolean') {
    if (typeof target.value !== 'boolean') {
      throw unsupported({
        harnessId,
        message:
          `ACP permission mapping for ${JSON.stringify(permissionMode)} assigns string value ` +
          `${JSON.stringify(target.value)} to boolean session configuration ${JSON.stringify(target.configId)}.`,
      });
    }
    return;
  }

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Use a configId that appears in the agent's advertised configOptions (listed in the error).
  2. Update the harness's permissionModeMapping for this mode to reference a valid config option id.
  3. Log sessionConfiguration.configOptions at session start to discover valid ids dynamically.

Example fix

// before
{ type: 'config', configId: 'permission-mode', value: 'bypassPermissions' }
// after (id the agent advertises)
{ type: 'config', configId: 'permission_mode', value: 'bypassPermissions' }
Defensive patterns

Strategy: validation

Validate before calling

const configIds = (sessionConfiguration.configOptions ?? []).map(o => o.id);
if (!configIds.includes(target.configId)) {
  throw new Error(`configId ${target.configId} not advertised; available: ${configIds.join(', ')}`);
}

Type guard

const hasConfigOption = (configId: string, cfg: SessionConfiguration): boolean =>
  (cfg.configOptions ?? []).some(o => o.id === configId);

Prevention

When it happens

Trigger: configureACPPermissionMode resolves the permissionMode to a { type: 'config', configId, value } mapping whose configId is not among sessionConfiguration.configOptions[].id.

Common situations: Mapping written for one ACP agent (e.g. Claude Code's config ids) reused with another agent; agent renamed config options between versions; typo in configId.

Related errors


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