{"record":{"id":"05146e29b9ac61a7","repo":"vercel/ai","slug":"acp-runtime-environment-key-json-stringify-key-05146e","errorCode":null,"errorMessage":"ACP runtime environment key ${JSON.stringify(key)} cannot be configured in both credentialEnv and env.","messagePattern":"ACP runtime environment key (.+?) cannot be configured in both credentialEnv and env\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/harness-acp/src/v1/implementation.ts","lineNumber":98,"sourceCode":"  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\nexport function createImplementationManifest({\n  implementation,\n}: {\n  implementation: ACPImplementation;\n}): string | undefined {\n  const { source } = implementation;\n  if (source.type === 'install-command') return undefined;\n  if (source.type === 'npm-locked') {\n    return source.packageJson;\n  }\n  return (\n    JSON.stringify(","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness-acp/src/v1/implementation.ts#L80-L116","documentation":"A key may not appear in both credentialEnv (vars handled as credentials) and env (static subprocess values). Putting a credential-shaped variable into env would persist its secret value in plain config, so the overlap is rejected eagerly.","triggerScenarios":"createACPV1 where a key in implementation.env also exists in implementation.credentialEnv, e.g. env: {GITHUB_TOKEN: 'ghp_...'} plus credentialEnv:['GITHUB_TOKEN'].","commonSituations":"Hardcoding a token into env for local testing while credentialEnv is also configured, or generated configs that add secrets to env instead of referencing the host value.","solutions":["Remove the key from env and let credentialEnv forward it from the host environment.","Store the secret in the host environment or a secret manager rather than embedding it in settings.","Scan config for the duplicated key before constructing the implementation."],"exampleFix":"// before\ncreateACPV1({ env: { GITHUB_TOKEN: 'ghp_x' }, credentialEnv: ['GITHUB_TOKEN'] });\n// after\ncreateACPV1({ credentialEnv: ['GITHUB_TOKEN'] }); // value supplied from host env","handlingStrategy":"validation","validationCode":"const creds = new Set(implementation.credentialEnv ?? []);\nconst dup = Object.keys(implementation.env ?? {}).filter(k => creds.has(k));\nif (dup.length > 0) throw new Error(`Secrets must not be inlined in env: ${dup.join(', ')}`);","typeGuard":"function envAndCredentialAreDisjoint(env, credentialEnv) {\n  const cr = new Set(credentialEnv ?? []);\n  return Object.keys(env ?? {}).every(k => !cr.has(k));\n}","tryCatchPattern":"try {\n  const impl = createACPV1(settings);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('both credentialEnv and env')) {\n    console.error('Remove the secret from env; supply it via the host environment');\n  }\n  throw err;\n}","preventionTips":["Never inline secret values in env; always use credentialEnv with host-supplied values","Scan configs for secret-shaped keys (TOKEN, KEY, SECRET) before inlining values","Store credentials in a secret manager instead of settings files"],"tags":["configuration","environment","security","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}