Yeachan-Heo/oh-my-codex · error

[sparkshell] raw fallback failed: executable is blocked (${e

Error message

[sparkshell] raw fallback failed: executable is blocked (${errno.code || 'blocked'})

What it means

spawnSync failed with an error classified as 'blocked' (e.g. EACCES/EPERM — the file exists but cannot be executed) while running the fallback program. The errno code is embedded in the message.

Source

Thrown at src/cli/sparkshell.ts:395

  const { announce = true, cause = 'native sidecar unavailable', nativePath = 'native-resolution', state = 'unavailable' } = options;
  const invocation = parseSparkShellFallbackInvocation(args);
  if (announce) {
    process.stderr.write(`[sparkshell] native sidecar unavailable; cause=${sanitizeFallbackDiagnostic(cause)}; path=${sanitizeFallbackDiagnostic(nativePath)}; state=${sanitizeFallbackDiagnostic(state)}; remediation=install a compatible native sidecar, reconnect for hydration, or set ${OMX_SPARKSHELL_BIN_ENV}. Falling back to raw command execution without summary support.\n`);
  }
  const result = spawnSync(invocation.argv[0], invocation.argv.slice(1), {
    cwd: process.cwd(),
    env: process.env,
    stdio: 'inherit',
    encoding: 'utf-8',
  });
  if (result.error) {
    const errno = result.error as NodeJS.ErrnoException;
    const kind = classifySpawnError(errno);
    if (kind === 'missing') {
      throw new Error(`[sparkshell] raw fallback failed: executable not found (${invocation.argv[0]})`);
    }
    if (kind === 'blocked') {
      throw new Error(`[sparkshell] raw fallback failed: executable is blocked (${errno.code || 'blocked'})`);
    }
    throw new Error(`[sparkshell] raw fallback failed: ${errno.message}`);
  }
  if (result.status !== 0) {
    process.exitCode = typeof result.status === 'number'
      ? result.status
      : resolveSignalExitCode(result.signal);
  }
}

export async function sparkshellCommand(args: string[]): Promise<void> {
  if (args[0] === '--help' || args[0] === '-h') {
    console.log(SPARKSHELL_USAGE);
    return;
  }

  if (args.length === 0) {
    throw new Error(`Missing command to run.\n${SPARKSHELL_USAGE}`);

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. `chmod +x $(which tmux)` or fix permissions on the executable
  2. Remove macOS quarantine: `xattr -d com.apple.quarantine /path/to/tmux`
  3. Remount or move binaries off noexec filesystems

Example fix

# before
sparkshell --tmux-pane 0  # EACCES
# after
chmod +x /usr/local/bin/tmux
sparkshell --tmux-pane 0
Defensive patterns

Strategy: validation

Validate before calling

import { accessSync, constants } from 'node:fs';
try { accessSync(bin, constants.X_OK); } catch { throw new Error(`${bin} is not executable`); }

Prevention

When it happens

Trigger: tmux exists but lacks the execute bit, or a security policy (macOS quarantine, AppArmor, noexec mount) denies execution.

Common situations: Binaries copied without +x, files downloaded on macOS flagged by Gatekeeper, /tmp mounted noexec in containers.

Related errors


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/8148902cdf72c362. Report an issue: GitHub.