vercel/ai · error

ACP runtime environment key

Error message

ACP runtime environment key ${JSON.stringify(key)} cannot be configured in both forwardEnv and credentialEnv.

What it means

A key listed in both forwardEnv (forwarded host env vars) and credentialEnv (securely handled credential vars) is ambiguous — the runtime cannot forward and credential-treat the same variable. createACPV1 rejects such overlap to keep environment handling deterministic. Keys are compared as an exact set intersection.

Solutions

  1. Remove the duplicated key from one of the two arrays — keep it in credentialEnv if it is a secret, otherwise forwardEnv.
  2. Audit both arrays with an intersection check before constructing the settings.
  3. If the var needs both behaviors, rename or split it (e.g. use a distinct credential var).

Example fix

// before
createACPV1({ forwardEnv: ['ANTHROPIC_API_KEY'], credentialEnv: ['ANTHROPIC_API_KEY'] });
// after
createACPV1({ credentialEnv: ['ANTHROPIC_API_KEY'] });
Defensive patterns

Strategy: validation

Validate before calling

const forwarded = new Set(implementation.forwardEnv ?? []);
const dup = (implementation.credentialEnv ?? []).filter(k => forwarded.has(k));
if (dup.length > 0) throw new Error(`Keys in both forwardEnv and credentialEnv: ${dup.join(', ')}`);

Type guard

function envListsAreDisjoint(a, b) {
  const setB = new Set(b ?? []);
  return !(a ?? []).some(k => setB.has(k));
}

Try / catch

try {
  const impl = createACPV1(settings);
} catch (err) {
  if (err instanceof Error && err.message.includes('both forwardEnv and credentialEnv')) {
    console.error('Remove the duplicated key from one list');
  }
  throw err;
}

Prevention

When it happens

Trigger: createACPV1 where any string appears in both implementation.forwardEnv and implementation.credentialEnv, e.g. forwardEnv: ['API_KEY'], credentialEnv: ['API_KEY'].

Common situations: Incrementally adding env vars to both lists while debugging auth, copy-pasting lists between forwardEnv and credentialEnv, or merging two config files that each list the same var.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at packages/harness-acp/src/v1/implementation.ts:86

  } else if (source.type === 'npm-simple') {
    validateNpmSimpleSource({ source });
  } else if (source.command.trim().length === 0) {
    throw new Error('ACP source.command must not be empty.');
  }
  if (!EXECUTABLE_NAME_REGEXP.test(implementation.executable)) {
    throw new Error(
      `ACP executable must be a bare command name without a path; received ${JSON.stringify(implementation.executable)}.`,
    );
  }

  validateForwardEnvironment({ forwardEnv: implementation.forwardEnv });
  validateForwardEnvironment({ forwardEnv: implementation.credentialEnv });
  validateEnvironment({ env: implementation.env });
  const forwardedKeys = new Set(implementation.forwardEnv ?? []);
  const credentialKeys = new Set(implementation.credentialEnv ?? []);
  for (const key of credentialKeys) {
    if (forwardedKeys.has(key)) {
      throw new Error(
        `ACP runtime environment key ${JSON.stringify(key)} cannot be configured in both forwardEnv and credentialEnv.`,
      );
    }
  }
  for (const key of Object.keys(implementation.env ?? {})) {
    if (forwardedKeys.has(key)) {
      throw new Error(
        `ACP runtime environment key ${JSON.stringify(key)} cannot be configured in both forwardEnv and env.`,
      );
    }
    if (credentialKeys.has(key)) {
      throw new Error(
        `ACP runtime environment key ${JSON.stringify(key)} cannot be configured in both credentialEnv and env.`,
      );
    }
  }
}

View on GitHub (pinned to 69428b1f8b)