vitessio/vitess · error

expected an underlying named type for %s, got %v

Error message

expected an underlying named type for %s, got %v

What it means

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.

Source

Thrown at go/vt/vtctl/vtctldclient/codegen/main.go:423

		}

		localImport := rewriteProtoImports(argNamed.Obj().Pkg())
		args = append(args, prefix+localImport+"."+argNamed.Obj().Name())
		argImports = append(argImports, typeArgImport{localImport: localImport, pkgPath: argNamed.Obj().Pkg().Path()})
	}

	return "[" + strings.Join(args, ", ") + "]", argImports, nil
}

func extractLocalPointerType(v *types.Var) (name string, localImport string, pkgPath string, err error) {
	ptr, ok := v.Type().(*types.Pointer)
	if !ok {
		return "", "", "", fmt.Errorf("expected a pointer type for %s, got %v", v.Name(), v.Type())
	}

	typ, ok := ptr.Elem().(*types.Named)
	if !ok {
		return "", "", "", fmt.Errorf("expected an underlying named type for %s, got %v", v.Name(), ptr.Elem())
	}

	name = typ.Obj().Name()
	localImport = rewriteProtoImports(typ.Obj().Pkg())
	pkgPath = typ.Obj().Pkg().Path()

	return name, localImport, pkgPath, nil
}

func extractRecvType(v *types.Var) (name string, localImport string, pkgPath string, err error) {
	named, ok := v.Type().(*types.Named)
	if !ok {
		return "", "", "", fmt.Errorf("expected a named type for %s, got %v", v.Name(), v.Type())
	}

	iface, ok := named.Underlying().(*types.Interface)
	if !ok {
		return "", "", "", fmt.Errorf("expected %s to name an interface type, got %v", v.Name(), named.Underlying())

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Point the pointer at a named type (e.g. *vtctldatapb.Message)
  2. Replace pointer-to-primitive params with named wrapper/proto types
  3. Extend extractLocalPointerType if support is required

Example fix

// before
Set(val *string) error
// after
Set(req *vtctldatapb.SetRequest) error
Defensive patterns

Strategy: type-guard

Validate before calling

// Pointer target must be a named type
p := v.Type().(*types.Pointer)
if _, ok := p.Elem().(*types.Named); !ok {
    return fmt.Errorf("%s points at unnamed type %v", v.Name(), p.Elem())
}

Type guard

func pointsAtNamed(v *types.Var) bool {
    p, ok := v.Type().(*types.Pointer)
    if !ok { return false }
    _, ok = p.Elem().(*types.Named)
    return ok
}

Prevention

When it happens

Trigger: A method parameter/receiver is a pointer to a basic, slice, map, or unnamed struct type, e.g. *string, *[]byte, *struct{...}.

Common situations: Adding an out-parameter style pointer-to-primitive to the interface; generics instantiations whose pointer target is unnamed; refactor left a parameter as *[]someType.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/ee9588a6b96392b6. Report an issue: GitHub.