{"record":{"id":"5bcfb667ccbff5ac","repo":"ruvnet/ruflo","slug":"invalid-container-name-containername","errorCode":null,"errorMessage":"Invalid container name: ${containerName}","messagePattern":"Invalid container name: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/commands/ruvector/import.ts","lineNumber":362,"sourceCode":"      output.writeln();\n\n      // Write to temp file for execution\n      const tempFile = path.join(process.cwd(), '.ruvector-import-temp.sql');\n      try {\n        fs.writeFileSync(tempFile, fullSQL);\n\n        output.printInfo('Executing import...');\n        output.writeln();\n        output.writeln(output.dim('Command:'));\n        output.writeln(output.dim(`  docker exec -i ${containerName} psql -U claude -d claude_flow < ${tempFile}`));\n        output.writeln();\n\n        // Execute via child_process (CRIT-02: use execFileSync to prevent command injection)\n        const { execFileSync } = await import('child_process');\n\n        // Validate containerName: alphanumeric, hyphens, underscores, dots only\n        if (!/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(containerName)) {\n          throw new Error(`Invalid container name: ${containerName}`);\n        }\n\n        try {\n          const sqlContent = fs.readFileSync(tempFile, 'utf-8');\n          const result = execFileSync('docker', [\n            'exec', '-i', containerName,\n            'psql', '-U', 'claude', '-d', 'claude_flow',\n          ], {\n            encoding: 'utf-8',\n            timeout: 60000,\n            input: sqlContent,\n          });\n\n          if (verbose) {\n            output.writeln(output.dim(result));\n          }\n\n          output.printSuccess('Import completed successfully!');","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/commands/ruvector/import.ts#L344-L380","documentation":"Thrown when the Docker container name used in the `docker exec` invocation fails the allow-list regex `^[a-zA-Z0-9][a-zA-Z0-9_.-]*$`. This is a command-injection guard (CRIT-02): the name is passed to execFileSync, but validating it defensively prevents a future refactor that shells out from introducing injection, and rejects obviously broken names early.","triggerScenarios":"Supplying a container name containing spaces, shell metacharacters ($, ;, |, &, backticks), slashes, or starting with a digit/symbol; or a name resolved from an untrusted config/env value.","commonSituations":"Container name read from an environment variable or user input without sanitization, a compose service name with a disallowed character, or accidentally passing `container:tag` (the image form) instead of just the container name.","solutions":["Pass a bare container name (the `Name` field from `docker ps`), not `image:tag` and not `host:port`.","Ensure the name matches `^[a-zA-Z0-9][a-zA-Z0-9_.-]*$` — strip any shell metacharacters from the source.","If the name comes from config, validate it at load time rather than at the docker call site."],"exampleFix":"// before\nconst containerName = 'my-container; rm -rf /';\n// after\nconst containerName = 'my-container';\nif (!/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(containerName)) {\n  throw new Error('bad container name');\n}","handlingStrategy":"validation","validationCode":"const VALID_CONTAINER = /^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/;\nfunction asContainerName(v: string): string {\n  if (!VALID_CONTAINER.test(v)) throw new Error(`Invalid container name: ${v}`);\n  return v;\n}","typeGuard":"const isValidContainerName = (v: unknown): v is string =>\n  typeof v === 'string' && /^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(v);","tryCatchPattern":"try {\n  await runDockerExec(containerName, sql);\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e);\n  if (msg.startsWith('Invalid container name')) {\n    console.error('Use a bare container name from `docker ps --format {{.Names}}`.');\n    process.exit(2);\n  }\n  throw e;\n}","preventionTips":["Source container names from `docker ps`, never from free-form input.","Pass the container name, not image:tag.","Validate at config load time, not at the call site."],"tags":["cli","validation","security","docker","command-injection"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}