{"record":{"id":"8270703869d66fc0","repo":"ruvnet/ruflo","slug":"command-not-allowed-cmd-split-0-827070","errorCode":null,"errorMessage":"Command not allowed: ${cmd.split(' ')[0]}","messagePattern":"Command not allowed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/deployment/src/validator.ts","lineNumber":283,"sourceCode":"    'npx ',\n    'git ',\n  ];\n\n  /**\n   * Execute command safely with validation\n   */\n  private execCommand(cmd: string, returnOutput = false): string {\n    // Validate: check for shell metacharacters\n    if (/[;&|`$()<>]/.test(cmd)) {\n      throw new Error(`Invalid command: contains shell metacharacters`);\n    }\n\n    // Validate: must start with allowed prefix\n    const isAllowed = Validator.ALLOWED_COMMAND_PREFIXES.some(\n      prefix => cmd.startsWith(prefix)\n    );\n    if (!isAllowed) {\n      throw new Error(`Command not allowed: ${cmd.split(' ')[0]}`);\n    }\n\n    try {\n      const output = execSync(cmd, {\n        cwd: this.cwd,\n        encoding: 'utf-8',\n        stdio: returnOutput ? 'pipe' : 'inherit',\n        timeout: 60000, // 60 second timeout for builds\n        maxBuffer: 50 * 1024 * 1024, // 50MB buffer for build output\n      });\n      return returnOutput ? output : '';\n    } catch (error) {\n      if (returnOutput && error instanceof Error) {\n        throw error;\n      }\n      throw error;\n    }\n  }","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/deployment/src/validator.ts#L265-L301","documentation":"Validator only executes commands starting with 'npm run ', 'npm ', 'npx ', or 'git ' (Validator.ALLOWED_COMMAND_PREFIXES). The first token of anything else is reported back in the error. Note this list is narrower than Publisher's: pnpm and yarn are NOT allowed here.","triggerScenarios":"validate({ testCommand: 'pnpm test' }) or 'yarn test', 'node --test', 'jest', 'vitest run' — none matches an allowed prefix.","commonSituations":"pnpm/yarn workspaces assumed to work because Publisher's build allowlist accepts them; direct test-runner invocations copied from package.json scripts.","solutions":["Use npm-based forms: 'npm test', 'npm run test', 'npx jest', 'npx vitest run'","For non-npm toolchains, run validation outside the Validator class and pass only npm/npx/git strings to it"],"exampleFix":"// before\nvalidate({ testCommand: 'pnpm test' }); // throws: Command not allowed: pnpm\n\n// after\nvalidate({ testCommand: 'npx pnpm test' }); // or 'npm test' in a npm-managed repo","handlingStrategy":"validation","validationCode":"const ALLOWED = ['npm run ', 'npm ', 'npx ', 'git '];\nfunction isValidatorAllowedCommand(cmd: string): boolean {\n  return ALLOWED.some(p => cmd.startsWith(p));\n}\n// pnpm/yarn are NOT allowed here — normalize first\nconst test = pkgManager === 'pnpm' ? 'npx pnpm test' : 'npm test';\nif (!isValidatorAllowedCommand(test)) throw new Error('validator only runs npm/npx/git');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember Validator's allowlist is narrower than Publisher's — no pnpm/yarn prefixes","Prefer 'npm run <script>' for both testCommand and buildCommand"],"tags":["validation","security","allowlist","testing","npm"],"backgroundTag":"command-allowlist-rejected","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}