{"record":{"id":"ee9588a6b96392b6","repo":"vitessio/vitess","slug":"expected-an-underlying-named-type-for-s-got-v","errorCode":null,"errorMessage":"expected an underlying named type for %s, got %v","messagePattern":"expected an underlying named type for (.+?), got (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/vtctldclient/codegen/main.go","lineNumber":423,"sourceCode":"\t\t}\n\n\t\tlocalImport := rewriteProtoImports(argNamed.Obj().Pkg())\n\t\targs = append(args, prefix+localImport+\".\"+argNamed.Obj().Name())\n\t\targImports = append(argImports, typeArgImport{localImport: localImport, pkgPath: argNamed.Obj().Pkg().Path()})\n\t}\n\n\treturn \"[\" + strings.Join(args, \", \") + \"]\", argImports, nil\n}\n\nfunc extractLocalPointerType(v *types.Var) (name string, localImport string, pkgPath string, err error) {\n\tptr, ok := v.Type().(*types.Pointer)\n\tif !ok {\n\t\treturn \"\", \"\", \"\", fmt.Errorf(\"expected a pointer type for %s, got %v\", v.Name(), v.Type())\n\t}\n\n\ttyp, ok := ptr.Elem().(*types.Named)\n\tif !ok {\n\t\treturn \"\", \"\", \"\", fmt.Errorf(\"expected an underlying named type for %s, got %v\", v.Name(), ptr.Elem())\n\t}\n\n\tname = typ.Obj().Name()\n\tlocalImport = rewriteProtoImports(typ.Obj().Pkg())\n\tpkgPath = typ.Obj().Pkg().Path()\n\n\treturn name, localImport, pkgPath, nil\n}\n\nfunc extractRecvType(v *types.Var) (name string, localImport string, pkgPath string, err error) {\n\tnamed, ok := v.Type().(*types.Named)\n\tif !ok {\n\t\treturn \"\", \"\", \"\", fmt.Errorf(\"expected a named type for %s, got %v\", v.Name(), v.Type())\n\t}\n\n\tiface, ok := named.Underlying().(*types.Interface)\n\tif !ok {\n\t\treturn \"\", \"\", \"\", fmt.Errorf(\"expected %s to name an interface type, got %v\", v.Name(), named.Underlying())","sourceCodeStart":405,"sourceCodeEnd":441,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/vtctldclient/codegen/main.go#L405-L441","documentation":"The pointer check passed but the pointed-to element type must itself be a named type for the generator to derive name/import/pkgPath. This error fires for pointers to unnamed types, e.g. *map[K]V, *[]T, *string, or pointers to anonymous structs.","triggerScenarios":"A method parameter/receiver is a pointer to a basic, slice, map, or unnamed struct type, e.g. *string, *[]byte, *struct{...}.","commonSituations":"Adding an out-parameter style pointer-to-primitive to the interface; generics instantiations whose pointer target is unnamed; refactor left a parameter as *[]someType.","solutions":["Point the pointer at a named type (e.g. *vtctldatapb.Message)","Replace pointer-to-primitive params with named wrapper/proto types","Extend extractLocalPointerType if support is required"],"exampleFix":"// before\nSet(val *string) error\n// after\nSet(req *vtctldatapb.SetRequest) error\n","handlingStrategy":"type-guard","validationCode":"// Pointer target must be a named type\np := v.Type().(*types.Pointer)\nif _, ok := p.Elem().(*types.Named); !ok {\n    return fmt.Errorf(\"%s points at unnamed type %v\", v.Name(), p.Elem())\n}","typeGuard":"func pointsAtNamed(v *types.Var) bool {\n    p, ok := v.Type().(*types.Pointer)\n    if !ok { return false }\n    _, ok = p.Elem().(*types.Named)\n    return ok\n}","tryCatchPattern":null,"preventionTips":["Avoid *string, *[]T, *map[K]V parameters in codegen-driven interfaces","Use named proto wrapper types instead of pointer-to-primitive out-params"],"tags":["go","codegen","pointers","type-system"],"backgroundTag":"unsupported-parameter-type","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}