vercel/ai · error · HarnessBridgeCapabilityUnsupportedError

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

Error message

ACP permission mapping for ${JSON.stringify(permissionMode)} assigns boolean value ${JSON.stringify(target.value)} to select session configuration ${JSON.stringify(target.configId)}.

What it means

Mirror of the boolean case: the mapped permission target assigns a boolean value to a session config option the agent advertised as a 'select' type (which expects one of a fixed set of string values). validateTarget throws this unsupported error before sending the invalid value to the agent.

Source

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

      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;
  }
  if (typeof target.value !== 'string') {
    throw unsupported({
      harnessId,
      message:
        `ACP permission mapping for ${JSON.stringify(permissionMode)} assigns boolean value ` +
        `${JSON.stringify(target.value)} to select session configuration ${JSON.stringify(target.configId)}.`,
    });
  }
  const availableValues = configOption.options.flatMap(option =>
    'options' in option
      ? option.options.map(value => value.value)
      : [option.value],
  );
  if (!availableValues.includes(target.value)) {
    throw unsupported({
      harnessId,
      message:
        `ACP permission mapping for ${JSON.stringify(permissionMode)} requires value ` +
        `${JSON.stringify(target.value)} for session configuration ${JSON.stringify(target.configId)}, ` +
        `but the agent advertised ${formatChoices({ values: availableValues })}.`,

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Change the mapping value to one of the select option's allowed string values.
  2. Check the agent's advertised configOptions/options to see the valid choices.
  3. If the option should be boolean, correct the agent or the configId in the mapping.

Example fix

// before
{ type: 'config', configId: 'approval', value: true }
// after
{ type: 'config', configId: 'approval', value: 'auto-approve' }
Defensive patterns

Strategy: validation

Validate before calling

const opt = sessionConfiguration.configOptions?.find(o => o.id === target.configId);
if (opt && opt.type !== 'boolean' && typeof target.value !== 'string') {
  throw new Error(`config ${target.configId} (select) expects a string value`);
}

Type guard

const isSelectConfigValue = (opt: ConfigOption | undefined, value: unknown): value is string =>
  opt != null && opt.type !== 'boolean' && typeof value === 'string';

Prevention

When it happens

Trigger: configureACPPermissionMode resolves to a config target { configId, value: true|false } while configOption.type is 'select' (i.e. not boolean), so the code requires typeof value === 'string'.

Common situations: Mapping reused across agents where an option changed from boolean to a select with 'on'/'off' choices; authoring a mapping from a boolean example against a select-based agent.

Related errors


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