go-delve/delve · error
%s (type %s) is not a struct
Error message
%s (type %s) is not a struct
What it means
memberVariable found the parent expression but its real DWARF type is not a *godwarf.StructType, so field lookup cannot proceed. The expression treated a non-struct value as if it had fields.
Source
Thrown at pkg/proc/variables.go:1194
if v.closureAddr != 0 {
fn = v.bi.PCToFunc(v.Base)
if fn != nil {
cst := fn.extra(v.bi).closureStructType
v = v.newVariable(v.Name, v.closureAddr, cst, v.mem)
closure = true
}
}
}
structVar := v.maybeDereference()
structVar.Name = v.Name
if structVar.Unreadable != nil {
return structVar, nil
}
t, isstruct := structVar.RealType.(*godwarf.StructType)
if !isstruct {
return nil, fmt.Errorf("%s (type %s) is not a struct", vname, structVar.TypeString())
}
for _, field := range t.Field {
if field.Name == memberName {
return structVar.toField(field)
}
if field.Name == "&"+memberName && closure {
f, err := structVar.toField(field)
if err != nil {
return nil, err
}
return f.maybeDereference(), nil
}
}
return nil, fmt.Errorf("%s has no member %s", vname, memberName)
}
View on GitHub (pinned to a23773e6c3)
Solutions
- Check the actual type with 'print x' or x.TypeString() and fix the expression.
- Explicitly dereference pointers: eval (*ptr).field.
- Type-assert interfaces in the program or inspect the concrete value via iface.(data).
- Ensure the binary is built without optimization so types resolve as written.
Example fix
// before dlv> eval p.Name // p is *Person Command failed: p (type *main.Person) is not a struct // after dlv> eval (*p).Name
Defensive patterns
Strategy: type-guard
Validate before calling
parent, err := client.EvalVariable(scope, vname, cfg)
if err != nil { return err }
if parent.Kind != reflect.Struct {
return fmt.Errorf("%s has kind %s; dereference or assert before field access", vname, parent.Kind)
} Type guard
// Only evaluate x.field when x is really a struct value
func isStructVar(v *api.Variable) bool { return v.Kind == reflect.Struct }
if !isStructVar(parent) { return errors.New("not a struct; deref pointer first") } Try / catch
v, err := client.EvalVariable(scope, expr, cfg)
if err != nil && strings.Contains(err.Error(), "is not a struct") {
// retry with explicit dereference: (*expr).field
} Prevention
- Check types with `print` before field access
- Explicitly dereference pointers in eval expressions
- Build without optimization (-gcflags=all='-N -l') so declared types match runtime types
When it happens
Trigger: Evaluating 'x.field' where x's resolved type is a basic type, pointer that was not dereferenced, interface, or slice rather than a struct — so the StructType type assertion fails.
Common situations: Forgetting to dereference a pointer (need (*x).field or x.field only works via auto-deref for C-like access; in Delve use explicit deref), evaluating an interface without type assertion, typo making the expression resolve to a scalar.
Related errors
- can not watch %q
- unknown type: %T
- %s has no member %s
- could not decode first frame
- unable to find function context
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/d22c9d88e2b092db.
Report an issue: GitHub.