Spot the bug in this LangChain reliability wrapper that combines `with_retry` and `with_fallbacks` the wrong way
Click any words you think contain an error. Click again to unmark.
The order is reversed: retry must be the inner wrapper and fallback the outer; as written, fallback fires on the first failure and the retry only protects the composite, which already succeeded via Anthropic.
Picture two safety nets stacked under a trapeze. The bottom net is the backup catcher; the top net is a second-chance bounce for the first catcher. If you put the bottom net on top by mistake, the moment the first catcher misses, the trapeze artist falls straight into the backup catcher's arms. The bounce never gets a chance to help. The bounce only matters when it is closer to the artist than the backup is. Same with retry and fallback: retry only helps if it wraps the primary call directly, with the fallback sitting outside it as the last resort.
Detailed answer & concept explanation~6 min readEverything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example.
Everything important, quickly.
6 minutes: the inside-out composition rule, the buggy trace, the corrected trace, the generalization to other wrapper pairs, and the production three-layer stack.
# Wrong: fallback fires on first failure; retry never engages
reliable = primary.with_fallbacks([backup]).with_retry(stop_after_attempt=3)
# Right: retry attempts the primary; fallback only fires after retries exhaust
reliable = primary.with_retry(stop_after_attempt=3).with_fallbacks([backup])Real products, models, and research that use this idea.
- LangChain's own reliability documentation walks through this exact wrapper-ordering pattern as the canonical example.
- Several teams that adopted LangChain 0.3's reliability primitives report this bug as a common code-review catch.
- OpenAI and Anthropic SDKs ship native retry; relying on the SDK for retry and using with_fallbacks at the LangChain layer is the alternative pattern.
- Resilience libraries like Polly (.NET) and Resilience4j (JVM) document the same ordering rule for retry-fallback composition.
What an interviewer would ask next. Try answering before peeking at the approach.
QHow would you add exponential backoff to the retry layer in this composition?
QWhat goes wrong if you put with_circuit_breaker as the innermost wrapper?
Don't say thisRed flags and common mistakes that signal junior thinking. Click to expand.
Red flags and common mistakes that signal junior thinking. Click to expand.
Writing the wrappers left to right in the order you say the intent in English, instead of inside-out in the order the wrapping actually applies.
The night-before-the-interview bullets. Scan these on the way to the call.
Primary sources. Skim if you want the original framing.
Same topic, related formats. Practice these next.