{"record":{"id":"6f70100be93dafbe","repo":"mastra-ai/mastra","slug":"fail-custom-install-command","errorCode":"FAIL_CUSTOM_INSTALL_COMMAND","errorMessage":"FAIL_CUSTOM_INSTALL_COMMAND","messagePattern":"FAIL_CUSTOM_INSTALL_COMMAND","errorType":"error_code","errorClass":"MastraError","httpStatus":null,"severity":"error","filePath":"deployers/cloud/src/utils/deps.ts","lineNumber":114,"sourceCode":"  const args = ['install', '--legacy-peer-deps=false', '--force'];\n  const { success, error } = await runWithExeca({ cmd: pm, args, cwd: path });\n  if (!success) {\n    throw new MastraError(\n      {\n        id: 'FAIL_INSTALL_DEPS',\n        category: 'USER',\n        domain: 'DEPLOYER',\n      },\n      error,\n    );\n  }\n}\n\nexport async function runInstallCommand({ path, installCommand }: { path: string; installCommand: string }) {\n  logger.info('Running install command', { command: installCommand, path });\n  const { success, error } = await runWithExeca({ cmd: 'sh', args: ['-c', installCommand], cwd: path });\n  if (!success) {\n    throw new MastraError(\n      {\n        id: 'FAIL_CUSTOM_INSTALL_COMMAND',\n        category: 'USER',\n        domain: 'DEPLOYER',\n      },\n      error,\n    );\n  }\n}\n\nexport async function runScript({ scriptName, path, args }: { scriptName: string; path: string; args?: string[] }) {\n  const pm = detectPm({ path });\n  logger.info('Running script', { script: scriptName, pm });\n  const { success, error } = await runWithExeca({\n    cmd: pm,\n    args: pm === 'npm' ? ['run', scriptName, ...(args ?? [])] : [scriptName, ...(args ?? [])],\n    cwd: path,\n  });","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/deployers/cloud/src/utils/deps.ts#L96-L132","documentation":"runInstallCommand executes a user-supplied install command via `sh -c <installCommand>` in the given path. If the command exits non-zero, a MastraError with id FAIL_CUSTOM_INSTALL_COMMAND (category USER, domain DEPLOYER) is thrown wrapping the execa error. It lets deployers override the default dependency-install step.","triggerScenarios":"Calling runInstallCommand with an installCommand that fails — bad syntax, missing binary, or a real install error in the target directory.","commonSituations":"Custom command assumes a shell or binary not present in the deploy image; wrong cwd for the command; script exits non-zero due to env differences (CI vs local); typos in the custom install command.","solutions":["Run the exact installCommand manually in the target path to reproduce and fix the failure","Ensure required binaries exist in the deploy environment image","Use absolute paths or set cwd explicitly in the command","Log/print the wrapped execa error detail to see the shell's stderr"],"exampleFix":"// before\nawait runInstallCommand({ path: outDir, installCommand: 'pnpm i --frozen-lockfile' }); // pnpm missing in image\n// after\nawait runInstallCommand({ path: outDir, installCommand: 'npm ci' }); // npm guaranteed present","handlingStrategy":"try-catch","validationCode":"sh -n -c \"$INSTALL_COMMAND\" && echo 'syntax ok'\ncommand -v $(echo \"$INSTALL_COMMAND\" | awk '{print $1}') >/dev/null || echo 'binary missing'","typeGuard":null,"tryCatchPattern":"try {\n  await runInstallCommand({ path, installCommand });\n} catch (err) {\n  if (err instanceof MastraError && err.id === 'FAIL_CUSTOM_INSTALL_COMMAND') {\n    console.error('Custom command failed:', err.cause); // stderr of sh -c\n  } else throw err;\n}","preventionTips":["Test the exact install command in a container matching the deploy image","Keep custom commands simple; prefer package scripts over inline shell chains","Reference binaries by absolute path when PATH may differ","Set -e style chaining deliberately and check each step"],"tags":["install","deployment","shell","subprocess"],"backgroundTag":"dependency-install-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}