{"record":{"id":"d235573263ae574e","repo":"golang/go","slug":"cannot-instantiate-s-got-d-type-arguments-but-h","errorCode":null,"errorMessage":"cannot instantiate %s: got %d type arguments but have %d type parameters","messagePattern":"cannot instantiate (.+?): got (.+?) type arguments but have (.+?) type parameters","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/compile/internal/types2/instantiate.go","lineNumber":69,"sourceCode":"func 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].\n//\n// If expanding is non-nil, it is the Named instance type currently being\n// expanded. If ctxt is non-nil, it is the context associated with the current","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/compile/internal/types2/instantiate.go#L51-L87","documentation":"When instantiating a generic type with validate=true, Instantiate checks that the number of type arguments matches the number of declared type parameters. This error fires when the counts differ, including both numbers in the message for diagnosis. The type is confirmed generic (has type parameters) but the caller supplied the wrong number of arguments.","triggerScenarios":"Calling types.Instantiate(ctxt, genericType, wrongNumberOfArgs, true). For example, a type with 2 type parameters instantiated with 1 or 3 arguments: types.Instantiate(ctxt, mapType, []types.Type{intType}, true) for a Map[K, V].","commonSituations":"Mistakes in generic instantiation code where the argument count doesn't match. Changes to a generic type's parameter count (adding or removing a type parameter) without updating all instantiation call sites. Hard-coded type argument lists that go stale after refactoring.","solutions":["Dynamically build the type argument list based on TypeParams().Len()","Count type parameters before constructing type arguments to ensure they match","Add a unit test that verifies Instantiate succeeds for each generic type you process","When iterating over types, skip or log types where TypeParams().Len() != len(targs)"],"exampleFix":"// before\ninst, err := types.Instantiate(ctxt, genericType, []types.Type{intType}, true)\n\n// after\nn := genericType.TypeParams().Len()\ntargs := make([]types.Type, n)\nfor i := 0; i < n; i++ {\n    targs[i] = resolveTypeArg(genericType.TypeParams().At(i))\n}\ninst, err := types.Instantiate(ctxt, genericType, targs, true)","handlingStrategy":"type-guard","validationCode":"// Build type arguments dynamically based on type parameter count\nfunc instantiateWithCorrectArity(ctxt *types.Context, t types.Type) (types.Type, error) {\n    named, ok := t.(*types.Named)\n    if !ok {\n        return t, nil\n    }\n    tparams := named.TypeParams()\n    if tparams.Len() == 0 {\n        return t, nil\n    }\n    targs := make([]types.Type, tparams.Len())\n    for i := 0; i < tparams.Len(); i++ {\n        // Resolve type argument for each parameter\n        targs[i] = resolveTypeArg(tparams.At(i))\n    }\n    return types.Instantiate(ctxt, t, targs, true)\n}","typeGuard":"// Check that type argument count matches type parameter count\nfunc arityMatches(t types.Type, targs []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 len(targs) == 0\n    }\n    return tparams != nil && tparams.Len() == len(targs)\n}","tryCatchPattern":"// Handle instantiation errors gracefully\ninst, err := types.Instantiate(ctxt, t, targs, true)\nif err != nil {\n    if strings.Contains(err.Error(), \"type arguments but have\") {\n        // arity mismatch — log and skip this type\n        log.Printf(\"skipping %v: %v\", t, err)\n        return nil\n    }\n    return fmt.Errorf(\"instantiation failed: %w\", err)\n}","preventionTips":["Always derive the number of type arguments from TypeParams().Len(), never hard-code it","When a generic type's parameter count changes, use compiler errors to find all call sites","Add unit tests for each generic type that verify Instantiate succeeds with the correct arity","In type processing loops, skip types where TypeParams().Len() != len(targs)"],"tags":["go-types","go-generics","api-validation","type-instantiation","arity-mismatch"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}