vercel/ai · error
ACP source.pnpmWorkspaceYaml must not be empty.
Error message
ACP source.pnpmWorkspaceYaml must not be empty.
What it means
createACPV1 validates that an 'npm-locked' ACP source carries a non-empty pnpmWorkspaceYaml string. The npm-locked source type reproduces a workspace install from checked-in pnpm-lock.yaml and pnpm-workspace.yaml files, so an empty pnpm-workspace.yaml means the launch cannot faithfully reconstruct the dependency graph. This guard fails fast at construction instead of at install time.
Source
Thrown at packages/harness-acp/src/v1/implementation.ts:66
/^(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-]+)*)?$/;
const PACKAGE_NAME_REGEXP =
/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/;
const EXECUTABLE_NAME_REGEXP = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
const ENVIRONMENT_VARIABLE_NAME_REGEXP = /^[A-Za-z_][A-Za-z0-9_]*$/;
export function validateACPV1Implementation(
implementation: ACPImplementation,
): void {
const { source } = implementation;
if (source.type === 'npm-locked') {
if (source.packageJson.length === 0) {
throw new Error('ACP source.packageJson must not be empty.');
}
if (source.pnpmLockYaml.length === 0) {
throw new Error('ACP source.pnpmLockYaml must not be empty.');
}
if (source.pnpmWorkspaceYaml?.length === 0) {
throw new Error('ACP source.pnpmWorkspaceYaml must not be empty.');
}
} 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) {View on GitHub (pinned to 69428b1f8b)
Solutions
- Provide the actual contents of the repo's pnpm-workspace.yaml in source.pnpmWorkspaceYaml.
- If the project has no workspace file, omit the field entirely (undefined) instead of passing an empty string.
- Check the code that reads the file — it is swallowing errors and returning '' — and make it throw or skip the field.
Example fix
// before
createACPV1({ source: { type: 'npm-locked', packageJson, pnpmLockYaml, pnpmWorkspaceYaml: fs.readFileSync('pnpm-workspace.yaml', 'utf8') } }); // returns '' if missing
// after
createACPV1({ source: { type: 'npm-locked', packageJson, pnpmLockYaml, pnpmWorkspaceYaml: fs.existsSync('pnpm-workspace.yaml') ? fs.readFileSync('pnpm-workspace.yaml', 'utf8') : undefined } }); Defensive patterns
Strategy: validation
Validate before calling
if (source.type === 'npm-locked' && source.pnpmWorkspaceYaml != null && source.pnpmWorkspaceYaml.length === 0) {
throw new Error('pnpmWorkspaceYaml must be non-empty or omitted');
} Type guard
function hasPnpmWorkspaceYaml(source) {
return source.type !== 'npm-locked' || source.pnpmWorkspaceYaml == null || source.pnpmWorkspaceYaml.length > 0;
} Try / catch
try {
const impl = createACPV1(settings);
} catch (err) {
if (err instanceof Error && err.message.includes('pnpmWorkspaceYaml')) {
console.error('Fix npm-locked source: provide pnpm-workspace.yaml contents or omit the field');
}
throw err;
} Prevention
- Only set pnpmWorkspaceYaml when the file exists and was read successfully
- Treat empty-string file reads as errors in your config loader
- Omit the field (undefined) when the project has no workspace file
When it happens
Trigger: Calling createACPV1 with source.type === 'npm-locked' and source.pnpmWorkspaceYaml set to an empty string ('' or ' '). Note: undefined/null is allowed (the check is ?.length === 0), only explicitly-empty strings throw.
Common situations: Loading pnpm-workspace.yaml with a read that returns '' on failure (e.g. fs.readFileSync defaulting), building config programmatically from environment variables that are unset-to-empty, or copying config from a repo without a pnpm-workspace.yaml.
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
- ACP source.packageJson must not be empty.
- ACP npm package name is invalid: ${JSON.stringify(source.pac
- ACP npm package version must be an exact semantic version; r
- Invalid argument for parameter output: Invalid output type.
- Continuation maxAgeMs must be a positive integer.
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/edc6e0ca7334e77c.
Report an issue: GitHub.