{"record":{"id":"63b35ae1cc7e56bc","repo":"vercel/ai","slug":"acp-npm-package-version-must-be-an-exact-semantic","errorCode":null,"errorMessage":"ACP npm package version must be an exact semantic version; received ${JSON.stringify(source.packageVersion)}.","messagePattern":"ACP npm package version must be an exact semantic version; received (.+?)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/harness-acp/src/v1/implementation.ts","lineNumber":327,"sourceCode":"    ...implementation.env,\n  };\n}\n\nfunction validateNpmSimpleSource({\n  source,\n}: {\n  source: ACPNpmSimpleSource;\n}): void {\n  if (!PACKAGE_NAME_REGEXP.test(source.packageName)) {\n    throw new Error(\n      `ACP npm package name is invalid: ${JSON.stringify(source.packageName)}.`,\n    );\n  }\n  if (\n    source.packageVersion != null &&\n    !EXACT_SEMVER_REGEXP.test(source.packageVersion)\n  ) {\n    throw new Error(\n      `ACP npm package version must be an exact semantic version; received ${JSON.stringify(source.packageVersion)}.`,\n    );\n  }\n}\n\nfunction validateEnvironment({\n  env,\n}: {\n  env: Readonly<Record<string, string>> | undefined;\n}): void {\n  for (const [key, value] of Object.entries(env ?? {})) {\n    if (!ENVIRONMENT_VARIABLE_NAME_REGEXP.test(key)) {\n      throw new Error(\n        `ACP environment variable name is invalid: ${JSON.stringify(key)}.`,\n      );\n    }\n    if (value.includes('\\0')) {\n      throw new Error(`ACP runtime environment value for ${key} contains NUL.`);","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness-acp/src/v1/implementation.ts#L309-L345","documentation":"When provided, source.packageVersion for 'npm-simple' sources must be an exact semver (MAJOR.MINOR.PATCH, optional -prerelease/+build). Ranges like ^1.0.0, >=2, latest, or dist-tags are rejected so installs are reproducible. Omitting packageVersion entirely is allowed (meaning latest).","triggerScenarios":"createACPV1 with source.type 'npm-simple' and packageVersion values like '^1.2.3', '~2.0.0', '>=1', 'latest', '1.2', or 'v1.2.3' (leading v is not accepted by the regex).","commonSituations":"Copying a version range from package.json dependencies, using the string from `npm outdated`, or prefixing with 'v' as printed by some CLIs.","solutions":["Pin the exact version, e.g. '1.2.3', stripped of any range operators or 'v' prefix.","If you want the latest, delete packageVersion instead of passing 'latest'.","Get the exact version via `npm view <pkg> version` and paste it."],"exampleFix":"// before\ncreateACPV1({ source: { type: 'npm-simple', packageName: 'claude-code-acp', packageVersion: '^1.0.0' } });\n// after\ncreateACPV1({ source: { type: 'npm-simple', packageName: 'claude-code-acp', packageVersion: '1.4.2' } });","handlingStrategy":"validation","validationCode":"const EXACT_SEMVER_REGEXP = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/;\nif (source.packageVersion != null && !EXACT_SEMVER_REGEXP.test(source.packageVersion)) {\n  throw new Error(`packageVersion must be exact semver, got: ${source.packageVersion}`);\n}","typeGuard":"function isExactSemver(v) {\n  return v == null || /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/.test(v);\n}","tryCatchPattern":"try {\n  const impl = createACPV1(settings);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('exact semantic version')) {\n    console.error('Pin an exact x.y.z version (no ^, ~, v prefix, or ranges)');\n  }\n  throw err;\n}","preventionTips":["Resolve ranges to exact versions at config-generation time","Omit packageVersion instead of passing 'latest'","Strip any leading 'v' when copying versions from CLI output"],"tags":["configuration","validation","npm","semver"],"backgroundTag":"invalid-config-value","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}