ruvnet/ruflo · error · Error

${label} contains shell metacharacters

Error message

${label} contains shell metacharacters

What it means

Thrown by the internal validatePath() function in daemon.ts when a path contains shell metacharacters: semicolon (;), ampersand (&), pipe (|), backtick (`), dollar sign ($), or angle brackets (< >). These characters could enable command injection if the path is ever interpolated into a shell command, even though the current code paths use execFileSync (no shell on POSIX). This is defence-in-depth.

Source

Thrown at v3/@claude-flow/cli/src/commands/daemon.ts:377

    }
  },
};

/**
 * Validate path for security - prevents path traversal and injection
 */
function validatePath(path: string, label: string): void {
  // Must be absolute after resolution
  const resolved = resolve(path);

  // Check for null bytes (injection attack)
  if (path.includes('\0')) {
    throw new Error(`${label} contains null bytes`);
  }

  // Check for shell metacharacters in path components
  if (/[;&|`$<>]/.test(path)) {
    throw new Error(`${label} contains shell metacharacters`);
  }

  // Prevent path traversal outside expected directories
  if (!resolved.includes('.claude-flow') && !resolved.includes('bin')) {
    // Allow only paths within project structure
    const cwd = process.cwd();
    if (!resolved.startsWith(cwd)) {
      throw new Error(`${label} escapes project directory`);
    }
  }
}

/**
 * #1914: Resolve the `--workspace` flag to an absolute path, or return null
 * if it is absent / not a usable string. Rejects values with null bytes or
 * shell metacharacters (defence-in-depth — the value is later embedded in a
 * forked child's argv and compared against `ps`/`tasklist` output).
 */

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Remove shell metacharacters (;, &, |, `, $, <, >) from the path
  2. Use absolute paths that do not require shell expansion
  3. If the path legitimately contains '$', expand environment variables before passing to validatePath

Example fix

// before
const path = '/tmp/$USER/workspace;whoami';
validatePath(path, 'workspace');

// after
const user = process.env.USER || 'default';
const path = `/tmp/${user}/workspace`;
validatePath(path, 'workspace');
Defensive patterns

Strategy: validation

Validate before calling

const SHELL_META_RE = /[;&|`$<>]/;
function isShellSafePath(path: string): boolean {
  return !SHELL_META_RE.test(path);
}

if (!isShellSafePath(userPath)) {
  throw new Error('Path contains shell metacharacters');
}

Type guard

function isShellSafe(s: string): boolean {
  return !/[;&|`$<>]/.test(s);
}

Try / catch

try {
  validatePath(userPath, 'workspace');
} catch (e) {
  if (e instanceof Error && e.message.includes('shell metacharacters')) {
    // Expand env vars manually, then strip metacharacters
    userPath = userPath.replace(/\$\w+/g, (_, v) => process.env[v] || '');
    // Retry
  }
}

Prevention

When it happens

Trigger: A path string passed to validatePath() matches the regex /[;&|`$<>]/. For example, a workspace path like '/tmp/proj;rm -rf /' or '/var/$HOME/app'.

Common situations: A path was constructed from untrusted user input without sanitization; an environment variable containing shell expansions was used as a path; a test deliberately included metacharacters to exercise the validator.

Related errors


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