fixerr
Local-first, provider-agnostic error/fix memory with semantic search and smart deduplication
🎯 The Problem
Every developer repeatedly solves the same errors:
port already in useafter switching branchesModuleNotFoundErrorfor a package that was installed- Docker permission errors in CI/CD
- Environment-specific configuration issues
fixerr captures these errors and their fixes, then surfaces the solution automatically when the same failure reoccurs — saving you from reinventing the wheel.
✨ Key Features
🧠 Smart Error Deduplication
- Automatically detects recurring errors using deterministic fingerprints
- Tracks occurrence frequency (
seen 5x) and timestamps (first/last seen) - Upgrades lightweight Tier 1 captures to full Tier 2 records seamlessly
🔍 Hybrid Search
- Semantic search via embeddings (when AI backend available)
- Falls back to exact/error-code matching when offline
- Combines both for maximum recall and precision
🛡️ Privacy-First by Design
- 100% local: SQLite database on your machine, no telemetry
- Automatic redaction of secrets, API keys, and volatile tokens
- No account required, no server to maintain
🤖 Provider-Agnostic AI
- Default: Ollama (fully offline)
- Swap to OpenAI, Anthropic, Gemini, or OpenAI-compatible with one config
- Graceful degradation to text-only search when no AI backend available
💻 Beautiful Terminal Dashboard
- Interactive TUI built with Textual
- Search, filter, resolve/dismiss errors, copy fixes
- Recurrence badges (
×<count>) and occurrence metrics - Semantic clustering to spot your most costly error patterns
🚀 Installation
# Core (uses local Ollama by default)
pip install fixerr
# With specific AI providers
pip install fixerr[openai] # OpenAI / OpenAI-compatible
pip install fixerr[anthropic] # Anthropic (Claude)
pip install fixerr[gemini] # Google Gemini
pip install fixerr[all-providers] # Everything
Requires Python 3.9+. Works without any AI provider configured (offline text matching only).
⚡ Quick Start
Manual Capture
# Capture a failing command
some-command-that-fails 2>&1 | fixerr capture -c "some-command-that-fails"
# Record the fix
fixerr resolve 1 "increased timeout in docker-compose.yml"
# Search for similar errors later
fixerr search "connection refused on startup"
Automatic Capture (Recommended)
Zsh / Bash
Add to your ~/.zshrc or ~/.bashrc:
eval "$(fixerr shell-init zsh)" # zsh
eval "$(fixerr shell-init bash)" # bash
PowerShell Add to your PowerShell profile:
fixerr shell-init pwsh | Out-String | Invoke-Expression
Now failed commands are captured automatically — no extra step needed.
Explore Your Error History
fixerr dashboard # Interactive TUI
fixerr doctor # Check AI provider status
fixerr explain 5 # Get AI explanation for error #5
🔧 How It Works
- Capture: Errors are captured via
fixerr capture,fixerr run, or automatic shell hook - Redact: Secrets, API keys, emails, and volatile tokens are stripped/normalized
- Fingerprint: Deterministic hash identifies recurring errors (ignoring timestamps, paths, etc.)
- Store: SQLite database stores one record per unique error, with occurrence count
- Search:
- Semantic: Cosine similarity over embeddings (when AI backend available)
- Fallback: Jaccard token overlap over normalized text
- Hybrid: Combines both (Phase 2)
- Surface: When a similar error occurs, fixerr shows the most relevant past fix
📊 The Dashboard (fixerr dashboard)
Left Pane:
- Filterable, searchable error list with recurrence badges (
×<count>)
Right Pane:
- Metadata (first/last seen, occurrence count)
- Full error output and applied fix
- AI explanation (when available)
- Top 3 semantically similar past errors
Patterns tab:
- Clusters errors via k-means over embeddings to spot your most time-consuming issues
Keybindings:
| Key | Action |
|---|---|
j/k or ↑/↓ |
Navigate error list |
r |
Mark selected error resolved |
d |
Mark selected error won't-fix |
u |
Reopen resolved/won't-fix error |
e |
Generate/show AI explanation |
c |
Copy fix to clipboard |
s |
Focus search |
/ |
Focus filter chips |
p or 1-4 |
Switch tabs (All/Unresolved/Resolved/Patterns) |
q/Ctrl-C |
Quit |
🤖 AI Backends
Configure in ~/.fixerr/config.toml:
[ai]
provider = "ollama" # ollama | openai | openai-compatible | anthropic | gemini
embed_fallback = "ollama" # Used when provider can't embed (e.g. anthropic)
[ai.ollama]
host = "http://localhost:11434"
embed_model = "nomic-embed-text"
gen_model = "llama3"
[ai.anthropic]
api_key_env = "ANTHROPIC_API_KEY"
gen_model = "claude-haiku-4-5"
Switch providers via CLI:
fixerr config set ai.provider anthropic
fixerr config show # See effective config (secrets masked)
💡 Embedding in Other Tools
from fixerr import ErnestClient
client = ErnestClient()
# Surface a fix for stderr text (returns None if no confident match)
fix = client.surface(stderr_text)
# Search for similar errors in a project context
recent = client.search(
"build failed",
cwd="/path/to/project",
top_k=3
)
Wrap in try/except ImportError to make fixerr an optional dependency.
⚙️ Configuration
Environment Variables:
| Variable | Purpose | Default |
|---|---|---|
fixerr_CONFIG |
Path to config file | ~/.fixerr/config.toml |
fixerr_DB |
Path to SQLite store | ~/.fixerr/errors.db |
fixerr_SIM_THRESHOLD |
Similarity cutoff for auto-surfacing | 0.7 |
OLLAMA_HOST |
Ollama daemon URL | http://localhost:11434 |
Tune Tier 1 auto-capture via [capture] in ~/.fixerr/config.toml:
auto_capture: Enable/disablemin_exit_code: Minimum exit code to consider failureignore_commands: List of commands to ignore (e.g.["cd", "git status"])ignore_patterns: Regex patterns to ignoresurface_threshold: Similarity threshold for auto-surfacingquiet: Suppress non-essential output
Full reference: USAGE.md
🧪 Contributing
Issues and PRs welcome! To run the test suite:
# Install dev dependencies
pip install -e ".[dev,all-providers]"
# Run tests
pytest
# Check code style
ruff check .
Provider tests use mocks — no real API calls or Ollama instance needed.
📜 License
MIT © 2026 RaviRu11d
Metadata
Release files for fixerr 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fixerr-0.2.0.tar.gz | 60.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fixerr-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 112.2 kB
Release files / fixerr-0.2.0.tar.gz
| Download URL | fixerr-0.2.0.tar.gz |
|---|---|
| Size | 60.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9930c21d2bf86ad6724fae02c836558fe5844ce783ea11270ee39588da0aac56
|
|
BLAKE2b-256 checksum How to use checksums |
bd3af496cbd06128d0b7f012edfbc1564c56dfb80617d0e9a70cfa72d9e9c45a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / fixerr-0.2.0-py3-none-any.whl
| Download URL | fixerr-0.2.0-py3-none-any.whl |
|---|---|
| Size | 51.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4aabd49c8b879ea05ccc74dcec1866deb82edf7f9d071540e26c681395240c34
|
|
BLAKE2b-256 checksum How to use checksums |
2b4ef2dc48623ddb3339b0d4b0398c59488ca58a5c7fe9c890117d15879684bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|