ruvnet/ruflo · error · Error
Invalid command: contains shell metacharacters
Error message
Invalid command: contains shell metacharacters
What it means
The metacharacter guard applied to the buildCommand string handed to publishToNpm(): any of ; & | ` $ ( ) < > rejects the command before it reaches execSync (which does use a shell). Composite commands and command substitution are therefore blocked, not quoted.
Source
Thrown at v3/@claude-flow/deployment/src/publisher.ts:228
return returnOutput ? output : '';
} catch (error) {
throw error;
}
}
/**
* Execute command (for build scripts only - validated)
*/
private execCommand(cmd: string, returnOutput = false): string {
// Only allow npm/npx build commands for safety
const allowedPrefixes = ['npm run ', 'npm ', 'npx ', 'pnpm ', 'yarn '];
const isAllowed = allowedPrefixes.some(prefix => cmd.startsWith(prefix));
if (!isAllowed) {
throw new Error(`Disallowed command: only npm/npx/pnpm/yarn commands are permitted`);
}
// Validate no dangerous shell metacharacters
if (/[;&|`$()<>]/.test(cmd)) {
throw new Error(`Invalid command: contains shell metacharacters`);
}
try {
const output = execSync(cmd, {
cwd: this.cwd,
encoding: 'utf-8',
stdio: returnOutput ? 'pipe' : 'inherit'
});
return returnOutput ? output : '';
} catch (error) {
throw error;
}
}
}
/**
* Convenience function to publish to npm
*/
export async function publishToNpm(View on GitHub (pinned to fa13ee4ad6)
Solutions
- Create a package.json script that does the chaining ("build": "npm run clean && npm run bundle") and pass 'npm run build'
- Or pass skipBuild: true and run the composite build yourself before publishToNpm
Example fix
// before
await publisher.publishToNpm({ buildCommand: 'npm run clean && npm run build' }); // throws
// after
// package.json: "build": "npm run clean && npm run bundle"
await publisher.publishToNpm({ buildCommand: 'npm run build' }); Defensive patterns
Strategy: validation
Validate before calling
function isSingleShellFreeCommand(cmd: string): boolean {
return !/[;&|`$()<>]/.test(cmd);
}
if (!isSingleShellFreeCommand(buildCommand)) {
throw new Error('move chaining into a package.json script; pass "npm run <script>"');
} Prevention
- Put &&-chains inside package.json scripts, not in buildCommand
- Treat any of ; & | ` $ ( ) < > in a command string as a hard error in your own pipelines too
When it happens
Trigger: publishToNpm({ buildCommand: 'npm run clean && npm run build' }); 'npm run lint && npm test'; any build string with $( ), pipes, or output redirection.
Common situations: Release scripts that chain clean+build+test in one line; commands copied from CI YAML or package.json scripts that rely on && or subshells.
Related errors
- Invalid GCS object path: ${objectPath}
- Disallowed command: only npm/npx/pnpm/yarn commands are perm
- Invalid command: contains shell metacharacters
- Validation failed: ${result.error}
- Invalid container name: ${containerName}
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/faa059e54ba7c489.
Report an issue: GitHub.