ruvnet/ruflo · error · Error

Invalid container name: ${containerName}

Error message

Invalid container name: ${containerName}

What it means

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.

Source

Thrown at v3/@claude-flow/cli/src/commands/ruvector/import.ts:362

      output.writeln();

      // Write to temp file for execution
      const tempFile = path.join(process.cwd(), '.ruvector-import-temp.sql');
      try {
        fs.writeFileSync(tempFile, fullSQL);

        output.printInfo('Executing import...');
        output.writeln();
        output.writeln(output.dim('Command:'));
        output.writeln(output.dim(`  docker exec -i ${containerName} psql -U claude -d claude_flow < ${tempFile}`));
        output.writeln();

        // Execute via child_process (CRIT-02: use execFileSync to prevent command injection)
        const { execFileSync } = await import('child_process');

        // Validate containerName: alphanumeric, hyphens, underscores, dots only
        if (!/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(containerName)) {
          throw new Error(`Invalid container name: ${containerName}`);
        }

        try {
          const sqlContent = fs.readFileSync(tempFile, 'utf-8');
          const result = execFileSync('docker', [
            'exec', '-i', containerName,
            'psql', '-U', 'claude', '-d', 'claude_flow',
          ], {
            encoding: 'utf-8',
            timeout: 60000,
            input: sqlContent,
          });

          if (verbose) {
            output.writeln(output.dim(result));
          }

          output.printSuccess('Import completed successfully!');

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Pass a bare container name (the `Name` field from `docker ps`), not `image:tag` and not `host:port`.
  2. Ensure the name matches `^[a-zA-Z0-9][a-zA-Z0-9_.-]*$` — strip any shell metacharacters from the source.
  3. If the name comes from config, validate it at load time rather than at the docker call site.

Example fix

// before
const containerName = 'my-container; rm -rf /';
// after
const containerName = 'my-container';
if (!/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(containerName)) {
  throw new Error('bad container name');
}
Defensive patterns

Strategy: validation

Validate before calling

const VALID_CONTAINER = /^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/;
function asContainerName(v: string): string {
  if (!VALID_CONTAINER.test(v)) throw new Error(`Invalid container name: ${v}`);
  return v;
}

Type guard

const isValidContainerName = (v: unknown): v is string =>
  typeof v === 'string' && /^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(v);

Try / catch

try {
  await runDockerExec(containerName, sql);
} catch (e) {
  const msg = e instanceof Error ? e.message : String(e);
  if (msg.startsWith('Invalid container name')) {
    console.error('Use a bare container name from `docker ps --format {{.Names}}`.');
    process.exit(2);
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12). Data as JSON: /api/errors/5bcfb667ccbff5ac. Report an issue: GitHub.