dagger/dagger · error
interface types must be named
Error message
interface types must be named
What it means
When parseGoTypeReference encounters a Go interface type, it requires the interface to be wrapped in a *types.Named so codegen can reference it by name (Dagger interfaces become named SDK types). An anonymous interface type (interface{...} used directly) has named == nil and triggers "interface types must be named".
Source
Thrown at cmd/codegen/generator/go/templates/module_types.go:118
}
typeName := named.Obj().Name()
if typeName == "" {
return nil, fmt.Errorf("struct types must be named")
}
moduleName := ""
if !ps.isDaggerGenerated(named.Obj()) {
moduleName = ps.moduleName
}
return &parsedObjectTypeReference{
name: typeName,
moduleName: moduleName,
isPtr: isPtr,
goType: named,
}, nil
case *types.Interface:
if named == nil {
return nil, fmt.Errorf("interface types must be named")
}
typeName := named.Obj().Name()
if typeName == "" {
return nil, fmt.Errorf("interface types must be named")
}
moduleName := ""
if !ps.isDaggerGenerated(named.Obj()) {
moduleName = ps.moduleName
}
return &parsedIfaceTypeReference{
name: typeName,
moduleName: moduleName,
goType: named,
}, nil
default:
return nil, fmt.Errorf("unsupported type for named type reference %T", t)
}View on GitHub (pinned to 82ba2681db)
Solutions
- Declare the interface as a named type: `type MyIface interface {...}` and use MyIface in signatures
- Replace anonymous interface{} / any fields with concrete named types or dagger.JSON
- For slices of interfaces, define a named interface element type: []MyIface
- Regenerate with dagger develop after renaming so the SDK picks up the interface
Example fix
// before
func Run(cb interface { Do() error }) error
// after
type Callback interface { Do() error }
func Run(cb Callback) error Defensive patterns
Strategy: validation
Validate before calling
// reject anonymous interfaces in module API signatures
func noAnonIfaces(f *ast.FuncDecl) error {
var bad bool
ast.Inspect(f.Type, func(n ast.Node) bool {
if it, ok := n.(*ast.InterfaceType); ok && len(it.Methods.List) >= 0 {
// only flag unnamed contexts: params/results/fields, not top-level TypeSpecs
bad = bad || !isInsideTypeSpec(n)
}
return true
})
if bad { return fmt.Errorf("declare the interface as `type X interface{...}`") }
return nil
} Type guard
func isAnonymousInterface(t ast.Expr) bool {
_, ok := t.(*ast.InterfaceType)
return ok
} Try / catch
if err != nil && err.Error() == "interface types must be named" {
return fmt.Errorf("declare the interface at package level, e.g. `type MyIface interface{...}`")
} Prevention
- Give every Dagger-facing interface a top-level name
- Avoid interface{} and any in module signatures; use dagger.JSON or concrete named types
- For slice-of-interface fields, name the interface element type
- Keep custom-interface implementations in the same module so codegen can name them
When it happens
Trigger: A module function param, return, or object field typed as an anonymous interface literal (e.g. field someInterface, or var x interface{ Method() }), or an interface reached via recursion paths that pass named=nil (aliases, slices).
Common situations: Using `any`/interface{} placeholders that codegen can't name; embedding anonymous interfaces in module APIs; writing []interface{...} elements; adopting Dagger custom interfaces without giving them top-level names.
Related errors
- unknown type %q
- enum types must be named
- failed to find decl for object %s: %w
- failed to find decl for named type %s: %w
- failed to find decl for method %s: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/da8d363fdbd46f48.
Report an issue: GitHub.