golang/go · error
%s does not %s %s (%s)
Error message
%s does not %s %s (%s)
What it means
Produced by types2 Checker.verify (src/cmd/compile/internal/types2/instantiate.go:228) when instantiating a generic type/function and a type argument fails to satisfy its type-parameter bound. The actual message text is assembled in Checker.implements via check.sprintf("%s does not %s %s (%s)", V, verb, T, detail); verify wraps the cause string in errors.New. The verb is 'satisfy' for constraints or 'implement' for interfaces, and detail explains the specific mismatch (e.g. 'X is not an interface', or a missing method).
Source
Thrown at src/cmd/compile/internal/types2/instantiate.go:228
}
panic(fmt.Sprintf("%v: %s", pos, msg))
}
// check may be nil; pos is used only if check is non-nil.
func (check *Checker) verify(pos syntax.Pos, tparams []*TypeParam, targs []Type, ctxt *Context) (int, error) {
smap := makeSubstMap(tparams, targs)
for i, tpar := range tparams {
// Ensure that we have a (possibly implicit) interface as type bound (go.dev/issue/51048).
tpar.iface()
// The type parameter bound is parameterized with the same type parameters
// as the instantiated type; before we can use it for bounds checking we
// need to instantiate it with the type arguments with which we instantiated
// the parameterized type.
bound := check.subst(pos, tpar.bound, smap, nil, ctxt)
var cause string
if !check.implements(targs[i], bound, true, &cause) {
return i, errors.New(cause)
}
}
return -1, nil
}
// implements checks if V implements T. The receiver may be nil if implements
// is called through an exported API call such as AssignableTo. If constraint
// is set, T is a type constraint.
//
// If the provided cause is non-nil, it may be set to an error string
// explaining why V does not implement (or satisfy, for constraints) T.
func (check *Checker) implements(V, T Type, constraint bool, cause *string) bool {
Vu := V.Underlying()
Tu := T.Underlying()
if !isValid(Vu) || !isValid(Tu) {
return true // avoid follow-on errors
}
if p, _ := Vu.(*Pointer); p != nil && !isValid(p.base.Underlying()) {View on GitHub (pinned to b6b368adc5)
Solutions
- Read the parenthesized detail to identify the missing method or the non-interface bound, then satisfy it on the type argument.
- If the argument is correct, relax/fix the constraint (e.g. add the method to an embedded interface, or use constraints.Ordered / comparable correctly).
- For comparable constraints, switch to a comparable type argument or wrap the value.
- Re-check the generic signature against the call site after any refactor of the constraint.
Example fix
// before
package main
import "fmt"
type Stringer[T any] interface{ String() string }
func Print[T fmt.Stringer](v T) { fmt.Println(v.String()) }
func main() { Print(42) } // int has no String()
// after
type MyInt int
func (m MyInt) String() string { return fmt.Sprint(int(m)) }
func main() { Print(MyInt(42)) } Defensive patterns
Strategy: validation
Validate before calling
// Use types2 to pre-check that a type argument satisfies a generic constraint
// before committing to the instantiation at scale.
// (Conceptual; in real code, rely on the compiler error and adjust the type/constraint.)
func satisfiesConstraint(typeArg, constraintExpr string) bool {
// pseudo: invoke go/types Instantiate + Check in a test harness
return true // placeholder
} Type guard
// Narrow a type argument to a method-bearing constraint at compile time.
type Stringer interface { String() string }
func assertStringer[T any](v T) Stringer {
s, ok := any(v).(Stringer)
if !ok { panic("type argument does not satisfy fmt.Stringer constraint") }
return s
} Prevention
- Read the parenthesized detail to find the missing method or non-interface bound before changing code.
- Keep constraints minimal and well-documented so callers know what is required.
- Add unit tests that instantiate generics with representative type arguments to catch violations early.
- When narrowing a constraint, audit all existing instantiation sites.
When it happens
Trigger: Instantiating a generic type or function with a concrete type argument that does not meet its constraint: either the bound is not an interface at all, or the type lacks a required method, or the type is not in the constraint's type set. Examples: type T[P fmt.Stringer] instantiated with T[int]; type Set[T comparable] instantiated with Set[[]byte].
Common situations: Passing a non-comparable type to a comparable-constrained generic (slices, maps); passing a struct without a required method to a method-constrained generic; a constraint that was narrowed and old call sites no longer fit; cross-package generic API misuse.
Related errors
- failed to locate cmd/compile for target platform
- CC not set and no default found
- local imports disallowed
- file not found
- cannot import "main"
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/c42833281f5fd2d2.
Report an issue: GitHub.