{"record":{"id":"daf13c94347564ab","repo":"vercel/ai","slug":"acp-source-pnpmlockyaml-must-not-be-empty","errorCode":null,"errorMessage":"ACP source.pnpmLockYaml must not be empty.","messagePattern":"ACP source\\.pnpmLockYaml must not be empty\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/harness-acp/src/v1/implementation.ts","lineNumber":63,"sourceCode":"}\n\nconst EXACT_SEMVER_REGEXP =\n  /^(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-]+)*)?$/;\nconst PACKAGE_NAME_REGEXP =\n  /^(?:@[a-z0-9][a-z0-9._-]*\\/)?[a-z0-9][a-z0-9._-]*$/;\nconst EXECUTABLE_NAME_REGEXP = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;\nconst ENVIRONMENT_VARIABLE_NAME_REGEXP = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nexport function validateACPV1Implementation(\n  implementation: ACPImplementation,\n): void {\n  const { source } = implementation;\n  if (source.type === 'npm-locked') {\n    if (source.packageJson.length === 0) {\n      throw new Error('ACP source.packageJson must not be empty.');\n    }\n    if (source.pnpmLockYaml.length === 0) {\n      throw new Error('ACP source.pnpmLockYaml must not be empty.');\n    }\n    if (source.pnpmWorkspaceYaml?.length === 0) {\n      throw new Error('ACP source.pnpmWorkspaceYaml must not be empty.');\n    }\n  } 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 });","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness-acp/src/v1/implementation.ts#L45-L81","documentation":"validateACPV1Implementation also requires that a 'npm-locked' source includes non-empty pnpmLockYaml; the lockfile is needed for reproducible installs of the agent package. An empty string indicates the lockfile contents were not provided.","triggerScenarios":"Calling createACPV1 with a 'npm-locked' implementation whose pnpmLockYaml is '' — e.g. pnpm-lock.yaml not bundled, a read failure returning '', or the field forgotten in the config.","commonSituations":"Packaging scripts that copy package.json but forget pnpm-lock.yaml; monorepo configs pointing at the wrong lockfile path; CI artifact assembly missing the lockfile.","solutions":["Populate source.pnpmLockYaml with the actual pnpm-lock.yaml contents.","Fix the packaging/read step that produced an empty string (check file path and error handling).","Switch to source.type 'npm-simple' with validateNpmSimpleSource-compliant fields if a lockfile is genuinely unavailable."],"exampleFix":"// before\nconst pnpmLockYaml = await maybeRead('pnpm-lock.yaml'); // '' on failure\ncreateACPV1({ implementation: { source: { type: 'npm-locked', packageJson, pnpmLockYaml } } });\n// after\nconst pnpmLockYaml = await fs.readFile('pnpm-lock.yaml', 'utf8'); // throws if missing\nif (pnpmLockYaml.length === 0) throw new Error('pnpm-lock.yaml is empty');","handlingStrategy":"validation","validationCode":"if (source.type === 'npm-locked' && source.pnpmLockYaml.length === 0) {\n  throw new Error('source.pnpmLockYaml is empty; load pnpm-lock.yaml contents before createACPV1');\n}","typeGuard":null,"tryCatchPattern":"try {\n  createACPV1({ implementation });\n} catch (error) {\n  if (error instanceof Error && error.message.includes('pnpmLockYaml must not be empty')) {\n    throw new Error('Implementation packaging failed: pnpm-lock.yaml was not embedded');\n  }\n  throw error;\n}","preventionTips":["Include pnpm-lock.yaml in build artifacts and verify content length after packaging.","Use throwing file reads so missing lockfiles fail early.","Add a preflight validation of the whole source object (all fields non-empty) before createACPV1."],"tags":["acp","validation","configuration","pnpm"],"backgroundTag":"missing-config-value","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}