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
- 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.
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
- 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.
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
- ${toolsJson} must contain a JSON array of {name, description
- Invalid target format: ${target}. Use agent:<id> or human:<i
- Validation failed: ${result.error}
- Header JSON exceeds maximum size (${headerLen} > ${MAX_HEADE
- Invalid embedding model name: ${embeddingModel}
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/5bcfb667ccbff5ac.
Report an issue: GitHub.