$ shellfirm

Common Issues

Solutions for frequently encountered shellfirm problems

shellfirm not intercepting commands

Symptom: You type a dangerous command like rm -rf /tmp/test and it executes without a challenge prompt.

Solutions:

  1. Check that the shell hook is installed. Run:

    shellfirm status

    If shellfirm is not active, install the hook:

    shellfirm init --install
  2. Restart your shell. After installing hooks, you must restart your shell (open a new terminal window or tab) for changes to take effect.

  3. Check your shell config file. Verify the eval line is present:

    • Zsh: ~/.zshrc should contain eval "$(shellfirm init zsh)"
    • Bash: ~/.bashrc should contain eval "$(shellfirm init bash)"
    • Fish: ~/.config/fish/config.fish should contain shellfirm init fish | source
  4. Verify shellfirm is in your PATH:

    which shellfirm

    If this returns nothing, shellfirm is not in your PATH. Ensure the binary location is in your PATH variable.

Too many false positives

Symptom: shellfirm triggers on commands that are not actually dangerous for your workflow.

Solutions:

  1. Raise the minimum severity threshold:

    shellfirm config severity Medium

    This skips Info and Low severity patterns.

  2. Disable specific check groups that are not relevant:

    # ~/.shellfirm/settings.yaml
    disabled_groups:
      - heroku
      - azure
      - gcp
  3. Ignore specific pattern IDs:

    # ~/.shellfirm/settings.yaml
    ignores_patterns_ids:
      - "git:stash_drop"
      - "docker:rm_container"
  4. Use a lower challenge type to reduce friction:

    shellfirm config challenge Enter

Performance impact

Symptom: Shell feels slower after installing shellfirm.

Details: shellfirm's check pipeline typically completes in under 5ms per command. If you are experiencing noticeable slowness:

  1. Check for a large .shellfirm.yaml with many custom patterns. Each custom regex pattern adds to the matching time.

  2. Context detection commands (git rev-parse, kubectl config current-context) each have a 100ms timeout. If these tools are slow in your environment, they can add latency. Check if git and kubectl respond quickly:

    time git rev-parse --abbrev-ref HEAD
    time kubectl config current-context
  3. Disable blast radius if the filesystem scanning adds latency (in ~/.config/shellfirm/settings.yaml):

    blast_radius: false

MCP server not connecting

Symptom: AI agent cannot find or connect to shellfirm's MCP tools.

Solutions:

  1. Verify the binary is in PATH:

    which shellfirm

    The path shown must be accessible to the AI agent process.

  2. Check the MCP configuration. For Claude Code, verify ~/.claude.json or .claude.json:

    {
      "mcpServers": {
        "shellfirm": {
          "command": "shellfirm",
          "args": ["mcp"]
        }
      }
    }
  3. Test the MCP server manually:

    echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | shellfirm mcp

    You should see a JSON response with protocolVersion and serverInfo.

  4. Restart the AI agent after changing MCP configuration. Most agents load MCP config at startup.

  5. Check for conflicting MCP server names. If you have another MCP server named "shellfirm", rename one.

Blast radius not showing

Symptom: shellfirm intercepts commands but does not show blast radius information (file counts, sizes).

Solutions:

  1. Check that blast radius is enabled:

    shellfirm config show
  2. Blast radius only applies to certain patterns. Not all check patterns have blast radius computation. Filesystem operations (rm -rf, chmod) typically show blast radius; git and cloud operations may not.

  3. PathExists filters may block matches. Some patterns require the target path to exist. If the path in the command does not exist, the pattern may not trigger.

Wrapper not intercepting statements

Symptom: shellfirm wrap psql starts the session but does not intercept dangerous SQL.

Solutions:

  1. Check the statement delimiter. For SQL tools, the delimiter should be ;:

    wrappers:
      tools:
        psql:
          delimiter: ";"
  2. Check the active check groups. The wrapper may not have the right groups enabled:

    wrappers:
      tools:
        psql:
          check_groups:
            - psql
            - database
  3. Multi-line statements are buffered until the delimiter. If you type DROP TABLE and press Enter without a ;, the wrapper waits for more input.

Configuration file errors

Symptom: shellfirm reports YAML parsing errors or unexpected behavior.

Solutions:

  1. Validate your settings file:

    shellfirm status

    If there are parsing errors, they will be reported.

  2. Reset to defaults:

    shellfirm config reset

    Choose "backup and replace" to keep your old settings.

  3. Check YAML syntax. Common issues:

    • Missing quotes around values with special characters
    • Incorrect indentation (YAML uses spaces, not tabs)
    • Missing colons between keys and values

Shell is completely locked up (deadlock)

Symptom: Every command you type is blocked — including shellfirm config reset, shellfirm init --uninstall, or even basic commands. Your terminal appears frozen or rejects every command.

Cause: The shell hook calls shellfirm pre-command before each command. If the shellfirm binary crashes or the settings file is corrupted, pre-command exits with an error, and the hook blocks the command. Since the hook also blocks shellfirm's own commands, you cannot use shellfirm to fix the problem.

Solution: manually remove the hook from your shell config file. Open your shell's configuration file in a text editor (or use another terminal/editor that doesn't source the shell config) and remove or comment out the shellfirm lines.

Step 1: Find and edit your shell config file

ShellConfig file
Zsh~/.zshrc
Bash~/.bashrc
Fish~/.config/fish/config.fish
Nushell~/.config/nushell/config.nu (Linux/macOS)
PowerShell~/.config/powershell/Microsoft.PowerShell_profile.ps1
Elvish~/.config/elvish/rc.elv
Xonsh~/.xonshrc
Oils~/.config/oils/oshrc

Open the file and look for lines starting with # Added by shellfirm init. Comment them out by adding # at the start:

# Added by shellfirm init
# eval "$(shellfirm init zsh)"

For Fish:

# Added by shellfirm init
# shellfirm init fish | source

For shells that embed the full hook (Nushell, PowerShell, Elvish, Xonsh), remove the entire block starting from # Added by shellfirm init down to the end of the hook code. See Shell Setup for the full hook snippets.

Step 2: Open a new terminal

The old terminal session still has the broken hook loaded in memory. Open a new terminal window or tab — it will start a clean shell without the shellfirm hook.

Step 3: Fix the underlying issue

Now that your shell works again, fix whatever caused the problem:

  • Corrupted settings file: Reset the configuration:
    shellfirm config reset
  • Outdated binary: Update shellfirm:
    # npm
    npm install -g shellfirm
    
    # Homebrew
    brew upgrade shellfirm
    
    # Cargo
    cargo install shellfirm
  • Settings file location: The settings file is at ~/Library/Application Support/shellfirm/settings.yaml (macOS) or ~/.config/shellfirm/settings.yaml (Linux). You can delete it to start fresh — shellfirm will use defaults.

Step 4: Re-enable the hook

Once the issue is resolved, reinstall the hooks:

shellfirm init

Then restart your shell (exec zsh, exec bash, or open a new terminal).

Tips to access your config file when locked out

If your terminal is completely unusable:

  • Use a GUI text editor like VS Code, TextEdit, or Finder to open the config file directly — these don't source your shell config.
  • Use a different shell that doesn't have the hook. For example, if zsh is broken, try bash --norc or /bin/sh.
  • SSH from another machine and edit the file remotely.