Amplifier Case Study
Cross-Repo
Bug Hunting
Following a bug across 3 repositories, 2 languages,
and a Python-to-Rust FFI boundary
Active Investigation
Based on developer-reported debugging sessions
The Symptom
501 Not Implemented
A voice feature in amplifier-chat started failing. Model downloads were broken. The error message was unhelpful.
What broke
Voice model downloads in amplifier-chat returned a 501 Not Implemented error. The feature that had been working simply… stopped.
The question
Nothing in amplifier-chat had changed. The code was the same. So where was the bug? And why was a download returning "Not Implemented"?
This is the kind of bug that makes engineers groan. The symptom is in one repo, but the cause could be anywhere in the dependency chain.
The Territory
Three repos. Two languages. One bug.
amplifier-chat
Python / TypeScript
Frontend application where the voice feature lives. This is where the symptom appeared — model downloads failing with a 501 error.
Surface Layer
amplifier-distro
Build System / Packaging
Distribution and dependency management. The amplifier-chat[voice] optional dependency pattern wasn't packaging voice dependencies correctly.
Middle Layer
amplifierd
Rust / PyO3
The daemon process with Rust code exposed to Python via PyO3 bindings. An async cancellation bug lurked at the FFI boundary.
Root Cause
Layer 1 · amplifier-chat
Starting at the surface
Observation
Voice downloads fail with 501
The voice model download endpoint returns "Not Implemented." But the endpoint exists, and the code to handle it hasn't changed.
Investigation
Check the dependency chain
The voice feature uses optional dependencies — amplifier-chat[voice]. If these aren't installed, voice features fall back to "not implemented." Could the dependencies be missing?
Finding
Dependencies aren't resolving
The optional dependency pattern is broken. Amplifier traces the issue upstream — something changed in how the distribution builds voice packages.
Layer 2 · amplifier-distro
Into the build system
The packaging problem
Changes in amplifier-distro altered how voice dependencies are bundled. The [voice] extras pattern that pip uses to install optional features was no longer resolving correctly.
Why it's tricky
Build system changes are invisible to application code. amplifier-chat didn't change — but the packages it received at install time did. Classic "works on my machine" territory.
But that wasn't the whole story
Fixing the dependency resolution would restore voice downloads. But in a separate Amplifier session investigating a related issue, a deeper bug was found — one that had been silently corrupting async operations at the Rust/Python boundary.
Layer 3 · amplifierd
The root cause:
async across an FFI boundary
In a separate Amplifier debugging session, a confirmed async cancellation bug was found in the Rust daemon (amplifierd), exposed through PyO3 bindings.
coordinator.request_cancel()
await coordinator.request_cancel()
The Rust function request_cancel() was exposed to Python as an async method via PyO3. But the calling code treated it as synchronous — creating a coroutine that was immediately discarded, never awaited, never executed.
The Challenge
Why async + FFI bugs are notoriously hard
Silent failure
Calling an async function without await doesn't throw an error. It silently creates a coroutine object that gets garbage collected. The operation simply never happens.
Cross-language boundary
The async nature of the function is defined in Rust, but the calling mistake happens in Python. No single-language linter catches this — it lives at the PyO3 FFI seam.
Intermittent symptoms
Cancellation bugs manifest as operations that "sometimes work" — they complete when they happen to finish before the cancel was needed, and fail silently when they don't.
A human debugger would need to: understand Python async semantics, understand Rust async semantics, understand how PyO3 bridges them, and know to look for unawaited coroutines at the boundary. Amplifier followed this thread across all three layers.
The Payoff
"Two changes needed."
After tracing the full call chain across three repositories, Amplifier immediately identified both required fixes — the dependency resolution in amplifier-distro and the async cancellation in amplifierd.
The Fix
Diagnose → Fix → Test → Merge
Step 1
Diagnose
Trace bug across repos
→
Step 2
Git Worktree
Isolate the fix branch
→
Step 3
Fix Rust Code
Correct the async call
→
Step 4
Run Tests
Verify the fix works
→
Step 5
Squash Merge
Clean commit history
Git worktrees for isolation
The developer created a git worktree to isolate the Rust fix from other work in progress. Amplifier guided the fix, the developer ran tests, and the change was squash-merged — a clean, auditable commit.
Cross-session coordination
The developer offered to "prompt amplifier-distro" from another session to make necessary build changes. Multiple Amplifier sessions working in parallel on coordinated fixes across repos.
The Pattern
Sessions coordinating with sessions
This debugging journey revealed a workflow pattern: a developer running multiple Amplifier sessions, each focused on a different repo, sharing context through the developer.
Session A
amplifier-chat — Identifies the 501 error, traces it to a dependency issue, reports finding to developer.
Session B
amplifierd — Finds the async cancellation bug in Rust/PyO3 code, fixes it, runs tests, merges.
Session C
amplifier-distro — Developer offers to "prompt amplifier-distro" to make coordinated build-system changes.
The developer acts as the coordinator, carrying context between focused sessions. Each session maintains deep context about its repo — the developer connects the dots between them.
Why This Matters
What this demonstrates about AI-assisted debugging
Following the thread
Amplifier didn't stop at the first plausible explanation. It traced the symptom (501 error) through the dependency layer (build system) to the root cause (async FFI bug) — across repo and language boundaries.
Polyglot fluency
The debugging required understanding Python async semantics, Rust async semantics, PyO3 FFI bindings, and how they interact. No single-language tool handles this. Amplifier operates across the full stack.
Instant diagnosis
After tracing the full call chain, Amplifier identified "two changes needed" immediately — no trial-and-error, no bisecting commits, no printf debugging. Trace the chain, find the cause, state the fix.
End-to-end workflow
Not just diagnosis — Amplifier participated in the full cycle: diagnose, create worktree, fix code, run tests, squash-merge. From symptom to shipped fix in a single workflow.
Reality Check
Without AI, this bug is a multi-day investigation.
Cross-repo async FFI bugs combine three of the hardest debugging challenges: distributed systems, language boundaries, and concurrency. Engineers who've chased these bugs know the cost.
By The Numbers
Investigation scope
2
Languages (Python + Rust)
2
Fixes identified instantly
Workflow: Diagnose → Git Worktree → Fix → Test → Squash Merge — all within Amplifier sessions, with cross-session coordination between repos.
Sources
Sources & Methodology
Data as of: March 2026
Feature status: Active — cross-repo debugging is a core Amplifier capability used in ongoing development
Story source:
- Narrative provided by the developer who conducted the debugging sessions
- Technical details (repo names, language stack, bug mechanism) from first-hand developer account
- Workflow details (git worktree, squash merge, cross-session coordination) from session observations
Repositories involved:
- amplifier-chat — Python/TypeScript frontend application
- amplifier-distro — Build system and packaging
- amplifierd — Rust daemon with PyO3 bindings
Gaps & limitations:
- Exact commit hashes, PR numbers, and timestamps not independently verified via git log
- Time-to-resolution not measured — "multi-day" human comparison is qualitative, based on engineering experience with similar bugs, not benchmarked
- Repository ownership/org not specified — names used as provided by developer
Attribution: Story reflects a real debugging workflow described by the developer who participated in the sessions
Try It
Your bugs don't
stay in one repo.
Neither should your debugging tools.
Amplifier traces bugs across repository boundaries, language boundaries, and FFI layers — following the thread wherever it leads.
More Amplifier Stories