# How Does thefuck Suggest Corrections for Failed Commands? A Technical Breakdown

> Discover how thefuck corrects your failed commands. It analyzes shell history and error output with dynamic rules to offer instant fixes for common command-line mistakes.

- Repository: [Vladimir Iakovlev/thefuck](https://github.com/nvbn/thefuck)
- Tags: internals
- Published: 2026-02-27

---

**thefuck suggests corrections by capturing the failed command from shell history, evaluating it against dynamically loaded rule modules that pattern-match error output, and ranking the resulting fixes by priority before presenting them for execution.**

When a shell command exits with an error, the **nvbn/thefuck** utility transforms that failure into a corrected command through a sophisticated multi-stage pipeline. This tool intercepts the failing command, analyzes its output against hundreds of specialized correction rules, and delivers the most appropriate fix either automatically or via an interactive prompt. Understanding how thefuck suggests corrections for failed commands reveals a sophisticated architecture that combines shell integration with pluggable Python modules.

## The Seven-Stage Correction Pipeline

The correction workflow orchestrated by `fix_command` in [`thefuck/entrypoints/fix_command.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/entrypoints/fix_command.py) follows a strict sequence that transforms raw shell errors into executable fixes.

### Stage 1: Capturing the Failed Command

The pipeline begins by retrieving the command that just failed. The `_get_raw_command` function in [`thefuck/entrypoints/fix_command.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/entrypoints/fix_command.py) (lines 13-26) extracts this either from arguments passed to the `fuck` alias or from the `TF_HISTORY` environment variable, which stores recent shell history.

When you invoke `thefuck` after a typo, the tool reads the previous command string before any processing occurs.

### Stage 2: Building the Command Object

Once captured, the raw script transforms into a structured `Command` object via `Command.from_raw_script` in [`thefuck/types.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/types.py) (lines 67-83). This object encapsulates both the original command string and its complete output (stdout and stderr), obtained through the `get_output` method.

This structured representation allows downstream rules to examine both what was typed and what error the system returned.

### Stage 3: Loading Enabled Rule Modules

The system dynamically discovers correction strategies through `get_rules` in [`thefuck/corrector.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/corrector.py) (lines 40-49). This function walks the `thefuck/rules/` directory, imports each Python module, and instantiates `Rule` objects.

Each rule module implements two critical functions:
- `match(command)`: A predicate returning `True` if the rule applies to the given error
- `get_new_command(command)`: A factory that generates the corrected command string

### Stage 4: Generating Correction Candidates

With rules loaded, the `get_corrected_commands` generator in [`thefuck/corrector.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/corrector.py) (lines 81-92) iterates through every enabled rule. For each rule where `rule.is_match(command)` returns `True`, the system calls `get_new_command` to yield one or more candidate fixes.

This evaluation happens against the fully populated `Command` object, allowing rules to inspect error messages, exit codes, and the original script simultaneously.

### Stage 5: Prioritization and Deduplication

Raw candidates often contain duplicates or vary in reliability. The `organize_commands` function in [`thefuck/corrector.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/corrector.py) (lines 52-78) solves this by sorting fixes according to their numeric **priority** (lower values rank higher) and removing duplicates.

Rules can specify their confidence level through priority values, ensuring that common fixes like `git` corrections surface before obscure edge cases.

### Stage 6: Interactive Selection

Depending on `settings.require_confirmation` defined in [`thefuck/conf.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/conf.py), the system either auto-selects the first candidate or engages the user. When confirmation is enabled (the default for interactive use), `select_command` in [`thefuck/ui.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/ui.py) (lines 59-80) launches a keyboard-driven interface.

This UI allows cycling through matches with arrow keys and confirming with Enter, or aborting the correction entirely.

### Stage 7: Execution and History Integration

Finally, the chosen `CorrectedCommand` executes through the `run` method in [`thefuck/types.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/types.py) (lines 47-62). This writes the corrected script to stdout for the shell to execute. When `settings.repeat` is enabled, the output wraps in a `|| thefuck --repeat …` fallback to handle cascading failures.

The method also updates shell history to reflect the correction, preventing the typo from appearing in future up-arrow recalls.

## Practical Usage Examples

### Interactive Correction Flow

Typical usage demonstrates the pipeline in action:

```bash
$ git brnch
git: 'brnch' is not a git command. See 'git --help'.

$ thefuck
git branch [enter/↑/↓/ctrl+c]

```

Here, the `git` rule matches the typo against known Git commands and suggests the correction with priority ordering.

### Non-Interactive Automation

For scripts or confident users, disable confirmation:

```bash
$ alias fuck='thefuck --no-ask'
$ rm -rf /
rm: cannot remove ‘/’: Is a directory

$ fuck
rm -rf ./*

```

The `--no-ask` flag bypasses `select_command` and immediately prints the first candidate from `organize_commands`.

### Developing Custom Rules

Extend the system by creating `~/.config/thefuck/rules/my_rule.py`:

```python
priority = 100

def match(command):
    return command.script.startswith('gti ')

def get_new_command(command):
    return command.script.replace('gti ', 'git ', 1)

```

This rule integrates into the standard pipeline, with `match` filtering for the typo and `get_new_command` generating the fix that `get_corrected_commands` will yield.

## Summary

- **thefuck** captures failed commands via `_get_raw_command` in [`thefuck/entrypoints/fix_command.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/entrypoints/fix_command.py), reading from `TF_HISTORY` or arguments.
- The `Command` class in [`thefuck/types.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/types.py) structures the script and output for rule analysis.
- `get_rules` in [`thefuck/corrector.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/corrector.py) dynamically loads Python modules from `thefuck/rules/` that implement `match` and `get_new_command`.
- `get_corrected_commands` evaluates every rule, while `organize_commands` sorts results by priority and removes duplicates.
- `select_command` in [`thefuck/ui.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/ui.py) handles interactive selection when `require_confirmation` is enabled.
- `CorrectedCommand.run` in [`thefuck/types.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/types.py) outputs the final script and manages shell history integration.

## Frequently Asked Questions

### How does thefuck know which command failed?

The tool retrieves the previous command from the `TF_HISTORY` environment variable or arguments passed to the alias. The `_get_raw_command` function in [`thefuck/entrypoints/fix_command.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/entrypoints/fix_command.py) handles this extraction, ensuring the pipeline always analyzes the correct failed script.

### Can I change which suggestions appear first?

Yes. Each rule specifies a `priority` attribute (lower numbers rank higher), and `organize_commands` in [`thefuck/corrector.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/corrector.py) sorts candidates accordingly. You can override priorities in your configuration or create custom rules with aggressive priority values to surface preferred fixes.

### What happens if multiple rules match the same error?

When multiple rules return `True` for `match(command)`, `get_corrected_commands` yields all their suggestions. The `organize_commands` function then deduplicates these and sorts by priority. If `require_confirmation` is disabled, the first (highest priority) candidate executes automatically; otherwise, `select_command` presents all options interactively.

### Is it possible to use thefuck without the interactive prompt?

Absolutely. Set `require_confirmation` to `False` in your configuration or use the `--no-ask` flag. This bypasses `select_command` in [`thefuck/ui.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/ui.py) and immediately outputs the first candidate from `organize_commands`, making the tool suitable for automation and scripting workflows.