{"record":{"id":"fa3d7a55dc5c1f21","repo":"vercel/ai","slug":"acp-runtime-environment-key-json-stringify-key","errorCode":null,"errorMessage":"ACP runtime environment key ${JSON.stringify(key)} cannot be configured in both forwardEnv and credentialEnv.","messagePattern":"ACP runtime environment key (.+?) cannot be configured in both forwardEnv and credentialEnv\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/harness-acp/src/v1/implementation.ts","lineNumber":86,"sourceCode":"  } else if (source.type === 'npm-simple') {\n    validateNpmSimpleSource({ source });\n  } else if (source.command.trim().length === 0) {\n    throw new Error('ACP source.command must not be empty.');\n  }\n  if (!EXECUTABLE_NAME_REGEXP.test(implementation.executable)) {\n    throw new Error(\n      `ACP executable must be a bare command name without a path; received ${JSON.stringify(implementation.executable)}.`,\n    );\n  }\n\n  validateForwardEnvironment({ forwardEnv: implementation.forwardEnv });\n  validateForwardEnvironment({ forwardEnv: implementation.credentialEnv });\n  validateEnvironment({ env: implementation.env });\n  const forwardedKeys = new Set(implementation.forwardEnv ?? []);\n  const credentialKeys = new Set(implementation.credentialEnv ?? []);\n  for (const key of credentialKeys) {\n    if (forwardedKeys.has(key)) {\n      throw new Error(\n        `ACP runtime environment key ${JSON.stringify(key)} cannot be configured in both forwardEnv and credentialEnv.`,\n      );\n    }\n  }\n  for (const key of Object.keys(implementation.env ?? {})) {\n    if (forwardedKeys.has(key)) {\n      throw new Error(\n        `ACP runtime environment key ${JSON.stringify(key)} cannot be configured in both forwardEnv and env.`,\n      );\n    }\n    if (credentialKeys.has(key)) {\n      throw new Error(\n        `ACP runtime environment key ${JSON.stringify(key)} cannot be configured in both credentialEnv and env.`,\n      );\n    }\n  }\n}\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness-acp/src/v1/implementation.ts#L68-L104","documentation":"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.","triggerScenarios":"createACPV1 where any string appears in both implementation.forwardEnv and implementation.credentialEnv, e.g. forwardEnv: ['API_KEY'], credentialEnv: ['API_KEY'].","commonSituations":"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.","solutions":["Remove the duplicated key from one of the two arrays — keep it in credentialEnv if it is a secret, otherwise forwardEnv.","Audit both arrays with an intersection check before constructing the settings.","If the var needs both behaviors, rename or split it (e.g. use a distinct credential var)."],"exampleFix":"// before\ncreateACPV1({ forwardEnv: ['ANTHROPIC_API_KEY'], credentialEnv: ['ANTHROPIC_API_KEY'] });\n// after\ncreateACPV1({ credentialEnv: ['ANTHROPIC_API_KEY'] });","handlingStrategy":"validation","validationCode":"const forwarded = new Set(implementation.forwardEnv ?? []);\nconst dup = (implementation.credentialEnv ?? []).filter(k => forwarded.has(k));\nif (dup.length > 0) throw new Error(`Keys in both forwardEnv and credentialEnv: ${dup.join(', ')}`);","typeGuard":"function envListsAreDisjoint(a, b) {\n  const setB = new Set(b ?? []);\n  return !(a ?? []).some(k => setB.has(k));\n}","tryCatchPattern":"try {\n  const impl = createACPV1(settings);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('both forwardEnv and credentialEnv')) {\n    console.error('Remove the duplicated key from one list');\n  }\n  throw err;\n}","preventionTips":["Keep secrets only in credentialEnv and non-secrets only in forwardEnv","Deduplicate merged config lists before constructing settings","Add a unit test asserting forwardEnv/credentialEnv disjointness"],"tags":["configuration","environment","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}