ruvnet/ruflo · error · Error

Invalid container name

Error message

Invalid container name: ${containerName}

What it means

Before execFileSync('docker', ['exec', '-i', <name>, 'psql', ...]) runs the SQL import, the ruvector import command validates the container name against ^[a-zA-Z0-9][a-zA-Z0-9_.-]*$ (CRIT-02 command-injection hardening). Slashes, colons, spaces, or a leading non-alphanumeric are rejected.

Solutions

  1. List actual containers: docker ps --format '{{.Names}}' and pass one of those names
  2. Restrict to alphanumerics, underscore, dot, dash, starting with an alphanumeric character
  3. If the container is unnamed, restart it with --name claude-flow-pg and use that

Example fix

# before
ruflo ruvector import --container postgres:16 ...

# after
docker ps --format '{{.Names}}'   # pick e.g. claude-flow-pg
ruflo ruvector import --container claude-flow-pg ...
Defensive patterns

Strategy: validation

Validate before calling

const CONTAINER_RE = /^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/;
if (!CONTAINER_RE.test(containerName)) {
  throw new Error(`'${containerName}' is not a container name — run: docker ps --format '{{.Names}}'`);
}
await runImport(containerName);

Type guard

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

Prevention

When it happens

Trigger: Passing an image reference like postgres:16 instead of a running container name, a registry path registry.io/app/db (slashes), or a name beginning with . or -.

Common situations: Confusing container name with image name; copy-pasting compose service definitions that use colons; assuming Docker's relaxed naming rules match the CLI's stricter subset.

Related errors


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

Appendix: 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 fa13ee4ad6)