Products · Product
Go
Raised as a usability problem by 559 people on Hacker News over 18 years (2009–2026), in 473 threads.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7Generics syntax is hard to readUnreviewed
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24Debugger is nearly unusableUnreviewed
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35Extremely slow to respondUnreviewed
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
Every issue, all time, most people first
Verbose error handling makes code easy to get wrongUnreviewed
20092026- Repetitive if err != nil checks clutter code everywhere2026-08-11
- Error handling feels clunky, with lots of boilerplate and simplistic error types2026-03-07
- Error checks are verbose and distracting, and happen constantly2026-03-07
GOPATH setup is confusing and awkward for developersUnreviewed
20092026- Environment variable setup for GOROOT and GOPATH is confusing and messy2023-09-15
- Confusing package, import and directory rules; mysterious import problems requiring constant doc reading2022-03-16
- Project setup and GOPATH/GOBIN settings feel confusing and add cognitive overhead2021-06-05
Hard to find which interfaces a type implements and whyUnreviewed
20092026- Hard to find the concrete implementation of an interface in large codebases2025-12-05
- Tools lacking Go To Implementation make it hard to find an interface's implementors2024-09-17
- Hard to find where a type implements an interface2024-09-04
Nil interface behaviour produces confusing code resultsUnreviewed
20092026- No compile-time nil checks and implicit interfaces cause easy-to-make mistakes2026-05-09
- Checking whether an interface is nil doesn't behave as expected2025-10-22
- Nil interface behavior is logical but not intuitive, so people often make mistakes2025-10-22
Unused variables and imports block compiling during prototypingUnreviewed
20092026- Refuses to compile with unused variables, blocking commenting-out debugging2025-08-22
- Compile fails on unused imports, forcing manual commenting or dummy uses while experimenting2024-05-07
- Commenting out code to debug fails because unused variables and imports block compilation2023-07-18
Generics syntax is hard to readUnreviewed
20092026- Generics syntax is hard to read2026-08-02
- Cryptic ~C syntax makes generics compile errors impossible to understand2026-08-02
- Can't require pointer methods, making generics frustrating to work around2022-03-26
Errors are nearly impossible to debug, with no stack tracesUnreviewed
20092026- Error logs gave no stack traces, so the 500s couldn't be diagnosed2024-01-05
- Hard to find where an error originated, wasting many minutes weekly2023-08-23
- Stackless errors are hard to debug2023-02-17
Can't tell what errors a function returns without reading its sourceUnreviewed
20092026- Can't tell which specific errors a function returns; compiler gives no help2025-12-05
- Can't tell what errors a function returns without reading its source code2025-05-11
- Cannot enumerate all errors a function can return, making user-facing error translation a nightmare2021-12-16
Channels are easy to misuse and the compiler does not catch mistakesUnreviewed
20092026- Channels are easy to misuse and the compiler does not catch the mistakes2024-06-26
- Selecting over an unknown number of channels is clumsy and unintuitive2018-10-15
- Easy to make mistakes: nil checks, frozen channels, and loop closure bugs2018-07-25
Cannot tell which errors a call can return, so errors get missedUnreviewed
20092026- Must handle errors at every callsite, though the commenter wants to handle them at a high level2023-03-17
- Errors without context make it hard to tell which call failed2022-09-08
- Every library returns a generic error type, so callers must read docs or code to learn what can be returned2022-06-14
Searching for Go resources returns clutter because go is a common wordUnreviewed
20092026- Searching for Go docs requires an awkward alternate name like golang2023-09-17
- Searching for the name 'go' returns too many unrelated results, making the language hard to find2020-08-19
- Hard to search for Go documentation because the name is a common word2016-04-08
Compiler warns for some ignored errors but silently allows othersUnreviewed
20092026- Errors get dropped silently and switching on errors is hard2025-06-03
- Returned errors can be silently ignored, with no compiler warning2023-06-20
- Compiler doesn't force handling errors, so they're easily ignored and error paths poorly documented2020-07-07
Docs are cryptic, so people rely on outside examplesUnreviewed
20092026- Docs list functions without explaining inputs, behavior, or working examples2024-11-08
- Detailed docs are hard to find and read, mostly confusing prose with examples2023-09-27
- Docs are cryptic and unhelpful, so people must rely on outside examples2023-09-17
Module system docs are missing or overwhelmingUnreviewed
20092026- Whole module system feels confusing and flaky to the developer2021-06-25
- Module system is confusing; docs are either missing or overwhelming2021-05-03
- Docs missing details on module resolution, making it confusing to learn2020-08-04
Converting a slice to interface slice silently forces huge allocationsUnreviewed
20092026- Slicing a slice with a larger bound silently exposes data that was cut off2023-03-19
- Slice behavior feels inexplicable and easy to misuse with non-obvious traps2022-06-10
- Sorting a slice needs boilerplate sort.Interface or a slice-casting workaround every time2018-09-02
Must cast values in and out of interface{} for general containersUnreviewed
20092026- Interface nesting rules are inconsistent, so implementations must match exact nested interface types2022-09-27
- Constrained interfaces look like regular ones, with no warning until compile fails2022-03-15
- Cannot cast []interface{} directly, so each value must be manually type-asserted2020-10-22
Template syntax and docs are unclear, so behaviour is unpredictableUnreviewed
20092026- Parsing, nesting and executing templates is confusing to work with2022-04-25
- Templates are confusing and frustrating to use, and docs don't say they're Go's2022-03-02
- Template syntax and docs are unclear, so behavior is hard to predict and costs lots of time2021-03-05
Unclear whether GitHub-style imports resolve locally or remotelyUnreviewed
20092026- Moving a project between git hosts requires touching every file's import lines2026-05-16
- Confused whether GitHub-style imports resolve to local folder or remote version2022-02-13
- Dependency versioning relies on maintainers' git tags; imports are full git URLs2017-11-05
Concurrency patterns are clunky, with verbose generics and ContextUnreviewed
20092026- Basic concurrency operations require ugly boilerplate that feels wrong2026-09-27
- Creating concurrency patterns is clunky: verbose generics, no traits, verbose Context2023-07-04
- Slice semantics make concurrent data races subtle and hard to reason about2022-06-10
Shorthand assignment silently shadows err and causes logic bugsUnreviewed
20092026- Shorthand declaration can silently shadow outer variables, which is confusing and easy to get wrong2024-11-27
- Implicit err shadowing with shorthand assignment silently causes subtle logic bugs2021-01-05
- Shadowing with := creates a silently unchecked err variable, so code doesn't do what it looks like2019-11-09
Errors are hard to chain or distinguish, and context is lostUnreviewed
20092026- Must add repetitive error and context boilerplate everywhere, and unclear when to wrap errors2026-03-07
- Developers must manually add context at every level, which is error-prone2024-04-05
- Errors passed up the stack are context-free, so they don't say what failed2020-11-30
General-purpose code requires copy-pasting near-identical code per typeUnreviewed
20092026- Writing general-purpose code means copy-pasting near-identical code for each type2022-03-15
- Writing generic behavior means copy-pasting and tweaking code repeatedly2015-06-05
- Simple reusable code needs heavy copy-paste and boilerplate instead of parameterized functions2014-08-24
Debugger is nearly unusableUnreviewed
20092026- Debugging options are horrible and have barely improved over the years2020-01-22
- Generated code is hard to debug and manage for complex cases2016-09-29
- Debugger is nearly unusable for the developer2015-08-05
Forgetting to assign append's result fails unpredictablyUnreviewed
20092026- Append() sometimes returns a new slice, so forgetting to assign the result fails unpredictably2025-04-13
- Excess slice capacity silently makes append overwrite data in another slice2024-01-24
- Append looks like a normal function but behaves as magic, tripping up new programmers2022-04-30
Go WebAssembly setup requires building Go from source and two versionsUnreviewed
20092026- Updating Go requires looking up docs and uninstalling the old version, unlike a one-command update2020-01-22
- Go get gets confused resolving a dependency needing a specific library version2019-11-16
- Running go mod tidy doesn't free disk space; dependencies stay cached in GOPATH2019-03-20
Dependency versioning is inconsistent, breaking compatibilityUnreviewed
20092026- Spent an hour unable to upgrade a dependency because the major version path change is unintuitive2022-03-04
- No built-in help for releasing versions or renaming packages; existing tools lag behind2019-12-03
- Dependency versioning and package management have been inconsistent and painful, breaking compatibility2019-11-16
Tag syntax mistakes fail silently with no compiler errorUnreviewed
20092026- Inconsistent separators in tag strings cause repeated headaches for developers2025-06-22
- Tags with double quotes need escaping and become an unreadable mess2016-01-25
- Malformed second tag fails silently with no compiler error, hard to track down2015-07-22
Must manually write a struct type for every JSON fieldUnreviewed
20092026- Parsing JSON fields that vary in type requires painful reflection2023-04-25
- Converting messy third-party JSON into a normalized structure is a painful chore in Go2021-12-19
- Must list every possible JSON field as a typed struct, which is tedious2017-12-06
Reader must stop and recheck which name is the typeUnreviewed
20092026- Syntax differs from other languages, so reading code makes the reader stop and recheck which name is the type2018-08-28
- Syntax is hard to read; keywords and delimiters are easy to miss or misread2013-05-14
- Variable names and types run together without a colon, so they are hard to tell apart2012-09-14
Documentation page is hard to read on mobileUnreviewed
20092026- The site is nearly unusable on mobile devices2018-11-02
- The page is hard to read on mobile devices2017-02-05
- Page is useless on mobile because fancy styling breaks text display2013-07-31
Build failures don't say that go generate must be runUnreviewed
20092026- Restarting gopls constantly and it fails silently on files with build tags2020-04-23
- Go's build system has been awful for a decade, only recently semi-decent2019-11-12
- Build failures don't tell you that go generate needs to be run2014-12-22
Adding context and cancellation takes extra effort and rolling own timeoutsUnreviewed
20092026- Adding context info and cancellation requires extra effort and rolling own timeouts2026-03-07
- Context-based cancellation is ugly and hard to use correctly; mutexes are error prone2025-12-05
- Basic timeout and cancellation handling is messy and easy to get wrong2016-08-02
Must manually check error types; fmt.Errorf errors silently don't matchUnreviewed
20092026- Library errors built with errors.New or fmt.Errorf can't be matched with errors.As2024-11-26
- Must manually hunt for error type; fmt.Errorf errors silently don't match2022-07-10
- Using fmt.Errorf for wrapping errors is considered awkward and distasteful by the commenter2019-04-29
Extremely slow to respondUnreviewed
20092026- Limited, surprising behaviour that is hard to debug and slow to use2024-08-13
- Extremely slow to respond, making it frustrating to use2020-01-22
- Game is untenably slow to interact with2013-02-02
Short variable declaration is confusing with several variables at onceUnreviewed
20092026- Confusing := versus = rules; removing one := line breaks code below it2018-07-24
- Unclear whether := creates new variables, causing hard-to-find shadowing bugs2015-01-18
- Typing := is a chore; confusing with several variables at once2014-10-17
Unscoped goroutines make programs hard to reason aboutUnreviewed
20092026- Goroutines are easy to leak and have no proper built-in way to cancel2026-09-27
- Unscoped goroutines make programs harder to reason about2022-07-02
- Easy to accidentally read or write shared globals from goroutines, causing errors2016-12-28
Hard to keep multiple Go modules in one repositoryUnreviewed
20092026- Hard to keep multiple Go modules in one repository2020-02-23
- Forced to keep all Go projects separate from other code in one workspace2017-01-10
- Go's fixed repo layout clashes with custom structures, breaking go get and multi-language repos2016-05-01
Implicit interface checks cause surprising bugsUnreviewed
20092026- Language hides complexity, implicit interfaces and interface{} make code hard to trace2021-03-22
- Implicit interface checks lead to surprising bugs for developers2020-10-25
- Often forced into unsafe interface{} code and needlessly verbose code, language blocks direct intent2014-06-29
Date format patterns are hard to read, with number-based layoutsUnreviewed
20092026- Date format patterns are hard to read and use, with arbitrary number-based layouts and month before day2023-11-20
- Date format string is complicated and hard for newcomers to understand2020-02-28
- Layout magic numbers are poorly documented, so users can't tell how to write a date format2015-01-25
Build tool can't pin or vendor dependency versions per projectUnreviewed
20092026- Source builds fail on dependencies and docs are wrong, forcing binary downloads2020-04-19
- Projects fail to build out of the box; figuring out the right standard library version is hard2018-08-14
- Build tool is frustratingly limited, can't pin or vendor dependency versions per project2016-08-21
Channel edge cases can deadlock the whole applicationUnreviewed
20092026- Hard to tell whether channel-based Go code terminates or deadlocks; requires jumping across code2026-09-27
- Channel deadlocks are hard to debug and closing them wrongly crashes the app2025-09-01
- Channels have subtle edge cases that can deadlock the whole application2022-06-11
Forces all code into one folder with repo-path importsUnreviewed
20092026- Forces all code into one deeply nested import-path directory, not a normal project layout2024-11-12
- Renaming a repo breaks imports, forcing edits to every file that imports it2024-08-12
- Forces all code into one folder and repo-path imports, which is annoying to work with2018-12-11
Must remember to reassign input slices, which are invalidatedUnreviewed
20092026- Easy to misuse: must remember which calls to reassign, since the input slice is invalidated2024-02-24
- Reversing a slice requires three lines of boilerplate every time2021-08-16
- Unclear which slice functions copy and which don't; easy to make mistakes2021-02-22
cgo is hard to set up on Windows, breaking simple buildsUnreviewed
20092026- Plugins must be compiled with the host and forced into cgo, making it hard to use2023-07-01
- Cgo is annoying to set up on Windows, breaking simple go build2023-01-27
- Setting up cgo on Windows leaves users stuck with no working path2022-02-04
Simple list handling requires constant index trackingUnreviewed
20092026- Three-index slice syntax like 2:3:3 is unintuitive compared to Python2024-08-11
- Writing slice index code for simple lists requires constant index thinking that other languages avoid2019-07-07
- Must hand-write push, pop and last-element helpers, and the slice[len(slice)-1] indexing is clumsy2019-03-14
Unreviewed issues were grouped by machine: Claude Haiku labelled each comment as a usability complaint, named what it's about and summed up the problem in a line, and a small model grouped similar problems. Nobody has checked them by hand. Expect mistakes.
The newest 50 complaints
- Goroutines are easy to leak and have no proper built-in way to cancel2026-09-27
- Hard to tell whether channel-based Go code terminates or deadlocks; requires jumping across code2026-09-27
- Basic concurrency operations require ugly boilerplate that feels wrong2026-09-27
- Variant data forces interface{} and nested dynamic dispatch, making code harder to write and read2026-08-18
- Repetitive if err != nil checks clutter code everywhere2026-08-11
- Full lint takes nearly 5 minutes, so the author skips running it locally2026-08-11
- Generics syntax is hard to read2026-08-02
- Cryptic ~C syntax makes generics compile errors impossible to understand2026-08-02
- Linting becomes slow, taking minutes in CI once many linters are enabled2026-07-26
- Url.Parse accepts almost any input without returning errors, hiding mistakes2026-05-25
- Moving a project between git hosts requires touching every file's import lines2026-05-16
- No compile-time nil checks and implicit interfaces cause easy-to-make mistakes2026-05-09
- Modifying a dependency to find a bug is very hard2026-05-08
- Hard to tell which unicode APIs to use; support is buried and undiscoverable2026-04-01
- Hard to debug because package names are unclear and hard to read2026-03-28
- Log level must be coded in advance or set at startup, not changed by whoever runs the code2026-03-18
- Adding context info and cancellation requires extra effort and rolling own timeouts2026-03-07
- Getting a traditional human-readable log format from slog is painful2026-03-07
- Error checks are verbose and distracting, and happen constantly2026-03-07
- Must add repetitive error and context boilerplate everywhere, and unclear when to wrap errors2026-03-07
- Error handling feels clunky, with lots of boilerplate and simplistic error types2026-03-07
- Syntax feels cumbersome and tedious to write by hand; package versioning is frustrating2026-03-02
- Must remember which stdlib APIs to avoid, with many exceptions2026-02-19
- Control flow is harder to follow; returned variables appear without explicit return2025-12-30
- Return value evaluation order is non-obvious; reader can't tell what the returned user will be2025-12-30
- Context-based cancellation is ugly and hard to use correctly; mutexes are error prone2025-12-05
- Hard to find the concrete implementation of an interface in large codebases2025-12-05
- Programmers can't tell whether values go to the heap without replicating compiler logic2025-12-05
- Can't tell which specific errors a function returns; compiler gives no help2025-12-05
- Error checking is verbose and stringly-typed, hard to handle errors well2025-12-04
- IDE features like find implementations run much slower than Java's, using more memory and CPU2025-11-25
- The standard library flag package is so bad that everyone uses third-party alternatives instead2025-11-24
- Removing an element needs awkward syntax and the underlying behavior is unclear2025-11-15
- Inserting or removing an element mid-slice is awkward and unclear what happens underneath2025-11-15
- Verbose error-checking boilerplate makes it easy to make mistakes2025-11-15
- Setting up an internal proxy for package downloads is fiddly2025-11-15
- Cryptic linter errors that can't be turned off, forcing tedious fixes just to pass CI2025-10-29
- Channels and append() have footguns that make shared data hard to reason about2025-10-29
- Checking whether an interface is nil doesn't behave as expected2025-10-22
- Nil interface behavior is logical but not intuitive, so people often make mistakes2025-10-22
- Nil pointers behave non-intuitively, which made the commenter abandon the language2025-10-22
- Test logs show the wrong callsite, so the source location is misleading2025-09-12
- Channel deadlocks are hard to debug and closing them wrongly crashes the app2025-09-01
- Must check whether libraries need manual init; IDE can't hint, pulling developers out of flow2025-08-23
- Linking two separate libraries into an application causes a terrible time2025-08-22
- Easy to pick the wrong clock, so programs get subtle time bugs2025-08-22
- Refuses to compile with unused variables, blocking commenting-out debugging2025-08-22
- Inconsistent APIs force constant documentation lookups for infrequently used functions2025-08-22
- Language is super confusing, hard for juniors and interns to write2025-08-22
- Non-intuitive nil behavior: an interface holding a nil pointer is not nil2025-08-22