Es Go Return (value, Error) Pairs
Fast recall
Quick revision
Core answer
Whether you understand Multiple Return Error beyond memorized syntax.
Giving a definition without explaining a practical trade-off.
Connect the concept to a small production example and state its complexity or failure mode.
Interview-ready guide
Interview answer
Go's founders looked at exception systems and rejected them for Go. Instead, an error is an ordinary value — usually the last return — and every caller decides, right at the call, what to do about it. The function signature itself tells you it can fail; there's no invisible throw path to go hunting for.
f, err := os.Open(path)
if err != nil {
return fmt.Errorf("load config: %w", err)
}That explicitness is the design. With exceptions, a call that can fail looks identical to one that can't — the failure exits through a side channel the compiler doesn't force you to acknowledge. With (value, error), the check is three lines you can see, and unused-variable rules mean you can't accidentally ignore the error entirely without the compiler noticing.
The cost is honest: Go code has more visible if err != nil branches than equivalent exception code has catch blocks. But the branches are where the handling actually lives, and their visibility is what keeps failure paths reviewed. You get to complain about the verbosity; you don't get surprise control flow.
Es Go Return (value, Error) Pairs
Direct Answer
Errors are values. The signature documents what can fail; the caller must handle it at the call site; multiple returns make the pairing natural.
Deep Dive & Architecture
What makes the pattern work is a set of small language decisions acting together:
- Multiple return values — the pair is expressible at all.
- The error interface — one method, any type can implement it, so failures can be as rich as needed.
- Unused-variable checking — you can't get the value without at least acknowledging the error slot (using _ on it is an explicit choice, not an accident).
- No exceptions — there is no competing failure channel, so the visible one is the real one.
The contrast with exception languages isn't verbosity so much as where the knowledge lives. A Java caller of a throwing method must read the docs to know it throws; the compiler enforces catch-or-declare but not understanding. A Go caller sees the error in the signature and handles it or visibly discards it. The information moved from prose to types.
The payoff shows in code review: a reviewer can see every failure path of a Go function by reading it. With exceptions, the same review needs the whole call graph. That's the deep reason Go chose this — not terseness, but auditability of failure.
Common Mistakes & Pitfalls
Giving a definition without explaining a practical trade-off.
Check your understanding
Answer these without looking back at the article.
- When would you use Multiple Return Error in a real project?
- How would you compare Multiple Return Error with an alternative?
- What is a common mistake when using Multiple Return Error?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.