# Minimum Required Functions for a TheFuck Rule: Match and Get_new_command Explained

> Learn the two essential functions, match and get_new_command, required for every thefuck rule. Understand how they determine and generate command corrections for thenvbn/thefuck plugin.

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

---

**Every thefuck rule must expose exactly two functions—`match(command)` to determine applicability and `get_new_command(command)` to generate the correction—or the engine will ignore the module.**

The `nvbn/thefuck` repository is a popular Python command-line tool that corrects errors in previous console commands. To extend its functionality with custom behaviors, developers create Python modules under `thefuck/rules/` that conform to a strict two-function contract recognized by the core engine.

## The Two Required Functions

The core engine in [`thefuck/main.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/main.py) dynamically imports every module in `thefuck/rules/` and inspects it for two specific callables. If either is missing, the rule is silently skipped.

### The `match` Function

The `match(command)` function receives a `thefuck.main.Command` object and returns a truthy value when the rule can fix the given error.

```python
def match(command):
    """Return True when this rule applies."""
    return 'error' in command.output.lower()

```

This function acts as the gatekeeper. According to the source code, the engine calls `match()` first; only if it returns `True` does it proceed to generate corrections.

### The `get_new_command` Function

The `get_new_command(command)` function generates one or more corrected command strings that thefuck suggests to the user.

```python
def get_new_command(command):
    """Return the corrected command."""
    return 'corrected-command'

```

This function can return a single string or a list of strings when multiple alternatives exist. The engine invokes this only after `match()` returns a truthy value.

## Optional Components

While only `match` and `get_new_command` are strictly required, rules often include additional attributes to modify behavior.

- **priority**: An integer that determines execution order. Higher values run first. For example, [`thefuck/rules/no_command.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/rules/no_command.py) sets `priority = 3000`.
- **side_effect**: A function `side_effect(old_cmd, command)` that executes after the user accepts a suggestion, used by rules like `dirty_unzip` to modify files.
- **Decorators**: Wrappers like `@sudo_support` or `@git_support` restrict rules to run only when underlying tools are available, as seen in [`thefuck/rules/git_push.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/rules/git_push.py).
- **Helper functions**: Private functions like `_get_used_executables` that assist the main logic but are ignored by the engine.

## Minimal Viable Rule Skeleton

The smallest possible valid rule requires only the two mandatory functions:

```python

# thefuck/rules/example.py

def match(command):
    """Return True when this rule applies."""
    return command.script == 'foo'

def get_new_command(command):
    """Return the corrected command."""
    return 'bar'

```

This skeleton satisfies the engine's requirements and will be loaded and executed if `match()` returns `True`.

## Real-World Examples from the Source Code

Examining the actual `nvbn/thefuck` source code reveals how required and optional components interact.

### The `no_command` Rule

Located in [`thefuck/rules/no_command.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/rules/no_command.py), this rule suggests valid commands when you mistype an executable name:

```python

# thefuck/rules/no_command.py

@sudo_support
def match(command):
    return (not which(command.script_parts[0]) and
            ('not found' in command.output or
             'is not recognized as' in command.output) and
            bool(get_close_matches(command.script_parts[0],
                                   get_all_executables())))

def get_new_command(command):
    old = command.script_parts[0]
    candidates = get_close_matches(old, get_all_executables())
    return [command.script.replace(old, c, 1) for c in candidates]

priority = 3000

```

This example demonstrates both required functions plus the optional `priority` attribute and `@sudo_support` decorator.

### The `unsudo` Rule

The [`thefuck/rules/unsudo.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/rules/unsudo.py) module provides a minimal implementation without optional components:

```python

# thefuck/rules/unsudo.py

patterns = ['you cannot perform this operation as root']

def match(command):
    if command.script_parts and command.script_parts[0] != 'sudo':
        return False
    return any(p in command.output.lower() for p in patterns)

def get_new_command(command):
    return ' '.join(command.script_parts[1:])

```

Here, `priority` defaults to `0` and no decorators are used, proving that only the two core functions are essential.

### The `git_push` Rule

Found in [`thefuck/rules/git_push.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/rules/git_push.py), this rule uses the optional `@git_support` decorator to ensure it only runs for git-related errors:

```python

# thefuck/rules/git_push.py

@git_support
def match(command):
    return ('push' in command.script_parts and
            'git push --set-upstream' in command.output)

def get_new_command(command):
    # Returns corrected git command

    pass

```

This illustrates how optional decorators complement the required function pair without replacing them.

## How the Engine Loads Rules

The rule discovery mechanism lives in [`thefuck/main.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/main.py). During initialization, the engine iterates through all Python files in `thefuck/rules/` and inspects each module for the `match` and `get_new_command` symbols. If both exist, the rule is registered; otherwise, the module is ignored. This strict contract ensures that every loaded rule can both detect its applicable scenario and provide a meaningful correction.

## Summary

- **Two functions are mandatory**: `match(command)` and `get_new_command(command)`.
- **Both receive** a `thefuck.main.Command` object containing the script and output.
- **Optional enhancements** include `priority`, `side_effect`, and decorators like `@git_support`.
- **File location**: Rules reside in `thefuck/rules/` as standard Python modules.
- **Engine behavior**: [`thefuck/main.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/main.py) loads only modules exposing both required functions.

## Frequently Asked Questions

### What happens if a rule is missing the `match` function?

The engine in [`thefuck/main.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/main.py) checks for both `match` and `get_new_command` when loading modules from `thefuck/rules/`. If either function is missing, the module is silently ignored and will not participate in error correction.

### Can a rule suggest multiple corrections?

Yes. While `get_new_command` can return a single string, returning a list of strings causes thefuck to present multiple suggestions. The `no_command` rule in [`thefuck/rules/no_command.py`](https://github.com/nvbn/thefuck/blob/main/thefuck/rules/no_command.py) uses this technique to suggest several close executable matches.

### Is the `priority` attribute required?

No. The `priority` attribute is optional and defaults to `0` when omitted. Rules with higher priority values execute before those with lower values, allowing fine-grained control over suggestion ordering.

### Can I use decorators like `@sudo_support` on any function?

Decorators like `@sudo_support` and `@git_support` are optional utilities found in the thefuck source code. They wrap the `match` function to check for tool availability before execution, but they are not required for a rule to function.