{"record":{"id":"20692f43ce98db1f","repo":"vercel/ai","slug":"acp-source-command-must-not-be-empty","errorCode":null,"errorMessage":"ACP source.command must not be empty.","messagePattern":"ACP source\\.command must not be empty\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/harness-acp/src/v1/implementation.ts","lineNumber":71,"sourceCode":"\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 });\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    }","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness-acp/src/v1/implementation.ts#L53-L89","documentation":"When the ACP source is neither 'npm-locked' nor 'npm-simple', it is treated as a direct command source and source.command must be a non-empty string. An empty command gives the launcher nothing to spawn, so createACPV1 rejects it eagerly. Whitespace-only commands are also rejected via trim().","triggerScenarios":"Calling createACPV1 with a source object whose type is not 'npm-locked'/'npm-simple' and source.command is '', ' ', or missing from a loosely typed config object.","commonSituations":"Unset CLI/executable config in YAML/JSON settings, environment-variable substitution that resolves to '', or copying a provider config template without filling in the command.","solutions":["Set source.command to the actual executable command that speaks ACP.","Verify which source branch your config falls into; if you meant an npm install, set type to 'npm-simple' or 'npm-locked' and fill its fields.","Check upstream config loading (env substitution, YAML parsing) that produces the empty string."],"exampleFix":"// before\ncreateACPV1({ source: { command: process.env.ACP_CMD ?? '' } });\n// after\nconst cmd = process.env.ACP_CMD;\nif (!cmd) throw new Error('ACP_CMD is required');\ncreateACPV1({ source: { command: cmd } });","handlingStrategy":"validation","validationCode":"if (source.type !== 'npm-locked' && source.type !== 'npm-simple' && (!source.command || source.command.trim().length === 0)) {\n  throw new Error('source.command is required for command sources');\n}","typeGuard":"function hasCommandSource(source) {\n  return source.type === 'npm-locked' || source.type === 'npm-simple' || (typeof source.command === 'string' && source.command.trim().length > 0);\n}","tryCatchPattern":"try {\n  const impl = createACPV1(settings);\n} catch (err) {\n  if (err instanceof Error && err.message === 'ACP source.command must not be empty.') {\n    console.error('Set source.command to the ACP server executable command');\n  }\n  throw err;\n}","preventionTips":["Fail config loading early when required command fields are absent","Validate env-var-driven config before constructing settings","Prefer npm-simple/npm-locked types when launching from a package"],"tags":["configuration","validation","process-launch"],"backgroundTag":"invalid-config-value","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}