Static Analysis for Go Error Type Consistency: errortype Linter I've been investigating a class of subtle bugs in Go error handling related to pointer vs. value semantics with errors.As, and developed a static analysis tool to detect these issues. I'm seeking feedback from the community on both the approach and the tool's effectiveness.
Problem Statement Consider this code attempting to handle AES key size errors: key := []byte("My kung fu is better than yours") _, err := aes.NewCipher(key) var kse *aes.KeySizeError if errors.As(err, &kse) { fmt.Printf("AES keys must be 16, 24 or 32 bytes long, got %d bytes.\n", kse) } else if err != nil { fmt.Println(err) } The bug: aes.NewCipher returns aes.KeySizeError as a value, but the code checks for a pointer to *aes.KeySizeError. This type mismatch causes errors.As to fail silently, with no compile-time detection. Analysis and Solution Approach The core issue is that Go's error interface allows both pointer and value types to implement error, but the dynamic type matching in errors.As requires exact type correspondence. This creates opportunities for silent failures when the expected and actual types don't align. I propose a two-part mitigation strategy: 1. Compile-time Intent Declaration Explicit compile-time assertions to document intended usage patterns: // MyValueError is intended to be used as a value var _ error = MyValueError{} // MyPointerError is intended to be used as a pointer var _ error = (*MyPointerError)(nil) 2. Static Analysis Tool I've developed errortype, a static analyzer that detects inconsistencies between intended error type usage and actual usage patterns. The tool analyzes: Function return value types Type assertions and type switches errors.As target parameters Method receiver consistency patterns Example diagnostic output: main.go:14:20: Target for value error "crypto/aes.KeySizeError" is a pointer-to-pointer, use a pointer to a value instead: "var kse aes.KeySizeError; ... errors.As(err, &kse)". (et:err) Request for Feedback I'm particularly interested in feedback on a few points: Prevalence: Have you encountered this pointer/value ambiguity with error types? How common do you think this class of bug is in practice? Solution Approach: What are your thoughts on using var _ error = ... assertions to declare an error type's intended usage? Is this a practical convention to adopt? Tooling: The detection heuristics are based on these assertions and usage pattern analysis. I would be grateful for any real-world testing on your codebases to validate their effectiveness and performance. The tool is currently CLI-only while I refine the detection logic based on real-world usage patterns. Integration is planned in a later phase. References Detailed analysis: https://blog.fillmore-labs.com/posts/errors-1/ Tool repository: https://github.com/fillmore-labs/errortype Playground example: https://go.dev/play/p/m4SEPqkZ2Zu I welcome any insights, particularly from those who have encountered similar issues or have thoughts on static analysis approaches for Go error handling patterns. Best regards, Oliver -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/0AF06538-3EAB-4E89-8F9A-25B7002237B8%40fillmore-labs.com.