vitessio/vitess · error

expected a named type for type argument %d of %s, got %v

Error message

expected a named type for type argument %d of %s, got %v

What it means

renderTypeArgs renders the type arguments of a generic named type. Each type argument must itself be a named type (optionally behind a single pointer) so it can be rendered as <import>.<Name>. This error fires when a type argument is anything else — a basic type, slice, map, or multi-level pointer.

Source

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

	if typeArgs.Len() == 0 {
		return "", nil, nil
	}

	args := make([]string, 0, typeArgs.Len())
	argImports := make([]typeArgImport, 0, typeArgs.Len())

	for i := 0; i < typeArgs.Len(); i++ {
		arg := typeArgs.At(i)

		var prefix string
		if ptr, ok := arg.(*types.Pointer); ok {
			prefix = "*"
			arg = ptr.Elem()
		}

		argNamed, ok := arg.(*types.Named)
		if !ok {
			return "", nil, fmt.Errorf("expected a named type for type argument %d of %s, got %v", i, named.Obj().Name(), arg)
		}

		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 {

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Change the offending type argument (position given in the message) to a named type such as a proto message
  2. Remove generics from the interface method parameter if primitives are required
  3. Extend renderTypeArgs in the codegen tool if support for such args is genuinely needed

Example fix

// before
Get[T any](ctx context.Context, req Wrapper[string]) error
// after
Get[T any](ctx context.Context, req Wrapper[*vtctldatapb.GetRequest]) error
Defensive patterns

Strategy: validation

Validate before calling

// Ensure each generic type argument is a named type
named := t.(*types.Named)
for i := 0; i < named.TypeArgs().Len(); i++ {
    arg := named.TypeArgs().At(i)
    if _, ok := arg.(*types.Named); !ok {
        return fmt.Errorf("type arg %d (%v) is not named", i, arg)
    }
}

Type guard

func hasNamedTypeArgs(t *types.Named) bool {
    for i := 0; i < t.TypeArgs().Len(); i++ {
        if _, ok := t.TypeArgs().At(i).(*types.Named); !ok { return false }
    }
    return true
}

Prevention

When it happens

Trigger: Declaring a method on the source interface whose parameter instantiates a generic with a non-named type argument, e.g. Wrapper[[]byte], Wrapper[string], Wrapper[**T], or Wrapper[map[K]V].

Common situations: Using generics in vtctldclient service interfaces with primitive type arguments; refactoring a proto-typed generic to a primitive; index i in the message tells which positional argument of the generic is the problem.

Related errors


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