interface conversion: type assertion failed
Go Programming Language
Severity: CriticalWhat Does This Error Mean?
This panic means you tried to assert that an interface value holds a specific type, but it actually holds a different type. For example: x.(string) — this asserts that x holds a string. If x actually holds an int, Go panics. Type assertions are how Go converts an interface value to a concrete type. The fix is to use the safe two-return form: value, ok := x.(string) — which never panics.
Affected Models
- Go 1.0 and later
- All Go versions
Common Causes
- Using the single-return form of a type assertion (x.(T)) when the interface might hold a different type
- Assuming an interface value holds a specific type without verifying it first
- A function returns an interface and you assert a specific type without checking
- An interface value is nil and you try to assert a type on nil
- The type was correct in a previous version of the code but changed and the assertion was not updated
How to Fix It
-
Use the safe two-value form: value, ok := x.(string) — if ok is true, the assertion succeeded. If false, value is the zero value and the assertion failed (no panic).
This is the standard Go pattern for safe type assertions. Always prefer this over the single-value form.
-
Check ok before using the value: value, ok := x.(string); if ok { fmt.Println(value) } else { fmt.Println('x is not a string') }
If you skip the ok check and use value when the assertion failed, value will be the zero value for the type (empty string, 0, false, etc.) — which can cause logic bugs.
-
Use a type switch to handle multiple possible types cleanly: switch v := x.(type) { case string: fmt.Println('string:', v) case int: fmt.Println('int:', v) default: fmt.Println('unknown type') }
Type switches are the idiomatic Go way to handle values that might be different types. They never panic.
-
Check whether the interface value is nil before asserting: if x != nil { value, ok := x.(string) }
Asserting a type on a nil interface always fails. A nil interface holds no type and no value.
-
Use fmt.Sprintf('%T', x) to print the actual type of the interface value for debugging: fmt.Printf('actual type is: %T\n', x)
The %T format verb prints the type name of any value. This helps you see what type the interface actually holds.
When to Call a Professional
Type assertion panics are always preventable. Never use the single-return form x.(T) unless you are absolutely certain of the type. Always use the safe two-return form: value, ok := x.(T) and check ok before using value.
Frequently Asked Questions
What is a type assertion in Go?
A type assertion extracts the concrete type from an interface value. Interfaces in Go hold a value of some concrete type — but you only know it as the interface type. A type assertion says 'I believe this interface holds a string — give me the string'. Syntax: concrete, ok := interfaceValue.(ConcreteType) If correct, concrete holds the typed value. If wrong, ok is false (safe form) or a panic occurs (unsafe form).
What is the difference between a type assertion and a type conversion?
A type assertion extracts a concrete value from an interface: x.(string) A type conversion converts one concrete type to another: int(myFloat) Type assertions only work on interface values — you cannot assert a type on a concrete int or string. Type conversions work on concrete types — you cannot convert an interface directly.
When should I use a type switch vs a type assertion?
Use a type assertion when you are confident about the type and only expect one possibility. Use a type switch when the value might be one of several different types and you need to handle each differently. For production code handling interface values from external sources, a type switch is usually safer and more readable than multiple if-then type assertions.