{"record":{"id":"26b8b9d22190e6df","repo":"golang/go","slug":"cannot-instantiate-non-generic-s-has-no-type-par","errorCode":null,"errorMessage":"cannot instantiate non-generic %s: has no type parameters","messagePattern":"cannot instantiate non-generic (.+?): has no type parameters","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/compile/internal/types2/instantiate.go","lineNumber":66,"sourceCode":"// for *Signature types, Instantiate will panic immediately if the type argument\n// count is incorrect; for *Named types, a panic may occur later inside the\n// *Named API.\nfunc Instantiate(ctxt *Context, orig Type, targs []Type, validate bool) (Type, error) {\n\tif ctxt == nil {\n\t\tctxt = NewContext()\n\t}\n\torig_, ok := orig.(genericType) // signature of Instantiate must not change for backward-compatibility\n\tif !ok {\n\t\tpanic(sprintf(nil, false, \"cannot instantiate non-generic %s: expected *Named, *Alias, or *Signature\", orig))\n\t}\n\tif len(targs) == 0 {\n\t\tpanic(sprintf(nil, false, \"cannot instantiate %s: empty type argument list\", orig))\n\t}\n\n\tif validate {\n\t\ttparams := orig_.TypeParams().list()\n\t\tif len(tparams) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"cannot instantiate non-generic %s: has no type parameters\", orig)\n\t\t}\n\t\tif len(targs) != len(tparams) {\n\t\t\treturn nil, fmt.Errorf(\"cannot instantiate %s: got %d type arguments but have %d type parameters\", orig, len(targs), len(tparams))\n\t\t}\n\t\tif i, err := (*Checker)(nil).verify(nopos, tparams, targs, ctxt); err != nil {\n\t\t\treturn nil, &ArgumentError{i, err}\n\t\t}\n\t}\n\n\tinst := (*Checker)(nil).instance(nopos, orig_, targs, nil, ctxt)\n\treturn inst, nil\n}\n\n// instance instantiates the given original (generic) function or type with the\n// provided type arguments and returns the resulting instance. If an identical\n// instance exists already in the given contexts, it returns that instance,\n// otherwise it creates a new one. If there is an error (such as wrong number\n// of type arguments), the result is Typ[Invalid].","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/compile/internal/types2/instantiate.go#L48-L84","documentation":"The Instantiate function (exported as go/types.Instantiate) creates a concrete type from a generic type by substituting type arguments. When called with validate=true on a type whose TypeParams().list() is empty, this error is returned. The type was recognized as a genericType (Named, Alias, or Signature) but has zero declared type parameters.","triggerScenarios":"Calling types.Instantiate(ctxt, nonGenericType, typeArgs, true) where the original type has no type parameters. For example, instantiating a plain *types.Named for a struct without type parameters, or a *types.Signature for a non-generic function.","commonSituations":"Dynamic type processing code (e.g., in code generators, serializers, or ORMs) that calls Instantiate on all types without checking if they are generic. Stale type information after refactoring a type from generic to non-generic. Reflection-based tools that enumerate and instantiate types programmatically.","solutions":["Check TypeParams().Len() > 0 before calling Instantiate","Only call Instantiate on types you have confirmed are generic","Pass validate=false if you do not need validation, but note that panics may occur later for *Named types with wrong argument counts","Cache genericness checks to avoid repeated TypeParams() calls in hot paths"],"exampleFix":"// before\ninst, err := types.Instantiate(ctxt, someType, targs, true)\n\n// after\nif someType.TypeParams().Len() == 0 {\n    return someType // not generic, no instantiation needed\n}\ninst, err := types.Instantiate(ctxt, someType, targs, true)","handlingStrategy":"type-guard","validationCode":"// Check if a type is generic before calling Instantiate\nimport (\n    \"go/types\"\n)\n\nfunc safeInstantiate(ctxt *types.Context, t types.Type, targs []types.Type) (types.Type, error) {\n    // Get type parameters from Named, Alias, or Signature\n    var tparams *types.TypeParamList\n    switch t := t.(type) {\n    case *types.Named:\n        tparams = t.TypeParams()\n    case *types.Alias:\n        tparams = t.TypeParams()\n    case *types.Signature:\n        tparams = t.TypeParams()\n    default:\n        return t, nil // not instantiable, return as-is\n    }\n    if tparams == nil || tparams.Len() == 0 {\n        return t, nil // not generic, no instantiation needed\n    }\n    return types.Instantiate(ctxt, t, targs, true)\n}","typeGuard":"// Type guard: returns true if the type has type parameters (is generic)\nfunc isGeneric(t types.Type) bool {\n    var tparams *types.TypeParamList\n    switch t := t.(type) {\n    case *types.Named:\n        tparams = t.TypeParams()\n    case *types.Alias:\n        tparams = t.TypeParams()\n    case *types.Signature:\n        tparams = t.TypeParams()\n    default:\n        return false\n    }\n    return tparams != nil && tparams.Len() > 0\n}","tryCatchPattern":null,"preventionTips":["Always check TypeParams().Len() > 0 before calling types.Instantiate with validate=true","Use a wrapper function (safeInstantiate) that handles the non-generic case gracefully","In dynamic type processing code, filter out non-generic types before the instantiation loop","Write unit tests covering both generic and non-generic types in instantiation code"],"tags":["go-types","go-generics","api-validation","type-instantiation"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}