Get AI summaries of any video or article — Sign up free
Why Go Will NEVER Fix Error Handling thumbnail

Why Go Will NEVER Fix Error Handling

The PrimeTime·
5 min read

Based on The PrimeTime's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Go is pausing error-handling syntax work for the foreseeable future because none of the proposals reached broad consensus under its proposal process.

Briefing

Go’s long-running effort to reduce the boilerplate of error handling is effectively stalled: after multiple Go-team proposals and hundreds of community alternatives, the project is choosing to stop pursuing new error-handling syntax “for the foreseeable future.” The core issue is familiar to Go programmers—repeated patterns like `if err != nil { return ... }` can turn real work into a thin layer surrounded by error-checking noise, especially in code that makes many API calls.

The Go team’s history shows how hard this problem has been to solve without breaking Go’s design priorities. The first major attempt dates to 2018, when Russ Cox described a “check and handle” approach based on earlier draft work by Marcel von Leoen Lohisen Laisen. That design included a broad comparison of alternatives, but it was judged too complicated. In 2019, a simplified “try” proposal followed, turning “check” into a `try` built-in function and omitting “handle.” While the mechanism was tested with a rewriting tool and prototyped in the compiler, it changed control flow by returning from the enclosing function—sometimes from deeply nested expressions—making the behavior harder to see and harder to reason about.

A later round of proposals continued to iterate, including a more recent direction attributed to Jimmy FRA that revisits the original check-and-handle concept with modifications intended to address earlier shortcomings. Yet even these refinements failed to win broad support. The proposal process itself becomes a bottleneck: when general consensus can’t be found in tracker discussions, proposals get declined, and without consensus the decision path ultimately falls to Go architects. The result is that none of the major syntax proposals reached the level of agreement needed to move forward.

One of the most concrete alternatives discussed is the “question mark” operator, borrowed from Rust’s ergonomics. Informal studies where programmers were shown Go code using this operator found that most participants correctly inferred its meaning. Ian Lance Taylor also built a tool to convert ordinary Go code into the proposed syntax and prototyped it in the compiler. Still, the proposal attracted a flood of comments and preferences for minor tweaks, and broad support never materialized.

Beyond consensus, the Go team highlights practical costs. Language changes are expensive: they require updating code, documentation, and tooling, and the Go team is small with many competing priorities. There are also arguments for leaving things alone—Go already has a workable error-handling model, and Go’s culture favors avoiding multiple ways to do the same thing. Even so, the team acknowledges the user pain: error handling remains a top complaint in developer surveys, and the lack of syntax support is most noticeable for programmers coming from languages with built-in error propagation.

In the end, the decision is pragmatic rather than optimistic. The team will stop pursuing syntax changes for error handling and close proposals focused primarily on error-handling syntax. The hope is that future work—possibly around improving how errors are constructed and augmented, or around better tooling and visibility—will clarify whether the real bottleneck is syntactic verbosity or the broader challenge of making errors useful and readable.

Cornell Notes

Go’s attempt to add new syntax to reduce error-handling boilerplate has stalled. After multiple proposals—including 2018 “check and handle,” a 2019 “try” built-in approach, and later ideas like a Rust-style question mark operator—none attracted the consensus needed to proceed under Go’s proposal process. The team cites both technical concerns (control-flow visibility, complexity) and social/process realities (hundreds of comments, lack of overwhelming agreement). The practical takeaway is a pause: for the foreseeable future, Go will stop pursuing error-handling syntax changes, even though error verbosity remains a top user complaint.

Why did the 2019 “try” proposal fail despite testing and compiler prototyping?

It altered control flow in a way that was easy to miss: using `try` could return from the enclosing function when an error occurred, including when errors arose inside deeply nested expressions. That hid control flow from the reader’s view, making the behavior less transparent and less palatable to many reviewers, even though the idea was close to patterns seen in other languages.

What made the “question mark” operator proposal attractive, and why didn’t it win?

It borrowed the Rust-style meaning of the operator and informal user studies found most participants could correctly infer what it did. Ian Lance Taylor also created a code-conversion tool and prototyped the feature in the compiler, showing a path to measurable impact. Yet broad support remained elusive as the proposal accumulated many comment-driven tweaks and preference-driven variations, preventing the consensus threshold from being met.

How does Go’s proposal process influence whether error-handling syntax can land?

The process aims for general consensus within tracker discussions and a timely path forward. If reviewers can’t identify consensus (or even a next step), proposals are declined. If consensus is unclear but outright decline isn’t warranted, the decision can move to Go architects—but even then, the team concluded that none of the error-handling proposals came close to the needed agreement.

What costs does the Go team point to when deciding whether to change the language?

Language changes are expensive beyond the syntax itself. They require updating existing code, documentation, and developer tools (including IDE support and related workflows). With a relatively small Go team and many other priorities, the ongoing maintenance and ecosystem adjustment burden weighs heavily.

What tension does the team highlight between “Go already works” and the desire to reduce boilerplate?

Some arguments favor the status quo because error handling is already functional, and adding syntax would mainly shift dissatisfaction from one group to another. The team also notes Go’s design preference to avoid multiple ways of doing the same thing. Still, the team acknowledges the persistent pain: error-handling verbosity remains a top complaint in surveys, especially for newcomers from languages with built-in error propagation.

Review Questions

  1. Which specific control-flow behavior of the 2019 `try` approach made it harder to review and reason about?
  2. What evidence supported the “question mark” operator’s usability, and what blocked it from becoming standard?
  3. Why does the Go team treat language changes as costly even when syntax ideas seem straightforward?

Key Points

  1. 1

    Go is pausing error-handling syntax work for the foreseeable future because none of the proposals reached broad consensus under its proposal process.

  2. 2

    The 2018 “check and handle” design was rejected as too complicated, even though it included extensive analysis and alternatives.

  3. 3

    The 2019 “try” proposal was rejected largely because it could return from the enclosing function from deeply nested expressions, obscuring control flow.

  4. 4

    A Rust-inspired “question mark” operator showed promising comprehension in informal studies and was prototyped, but it still failed to gain overwhelming support amid many tweak requests.

  5. 5

    Go’s small team and the ecosystem-wide cost of language changes (code, docs, tools) make syntax changes hard to justify without strong agreement.

  6. 6

    The team distinguishes between syntactic verbosity and the broader challenge of making errors useful, suggesting future work may focus more on error construction and tooling than syntax alone.

Highlights

Repeated `if err != nil { return ... }` checks can drown out the “real work” in Go functions, especially in API-heavy code.
The `try` proposal’s biggest drawback wasn’t the syntax—it was hidden control flow: errors could trigger returns from enclosing functions inside nested expressions.
The “question mark” operator drew interest because most people correctly guessed its meaning in informal tests, but consensus still never formed.
Go’s final decision is process-driven: without general agreement, proposals get declined, and the team concluded none came close enough to proceed.

Topics

  • Go Error Handling
  • Proposal Process
  • Question Mark Operator
  • Try Proposal
  • Language Design Costs

Mentioned

  • Russ Cox
  • Marcel von Leoen Lohisen Laisen
  • Jimmy FRA
  • Ian Lance Taylor