docker/cli · error
expected a pointer to a struct, got nil pointer
Error message
expected a pointer to a struct, got nil pointer
What it means
formatter.marshalMap (used by formatter.MarshalJSON for `--format json` output) requires a non-nil pointer to a struct because it reflects over the value's methods (Name(), ID(), etc.) to build the JSON map. It first checks the kind is reflect.Pointer, then checks val.IsNil(); a typed nil pointer passes the kind check but cannot have its methods safely invoked, so it is rejected explicitly instead of panicking inside reflection.
Source
Thrown at cli/command/formatter/reflect.go:31
// MarshalJSON marshals x into json
// It differs a bit from encoding/json MarshalJSON function for formatter
func MarshalJSON(x any) ([]byte, error) {
m, err := marshalMap(x)
if err != nil {
return nil, err
}
return json.Marshal(m)
}
// marshalMap marshals x to map[string]any
func marshalMap(x any) (map[string]any, error) {
val := reflect.ValueOf(x)
if val.Kind() != reflect.Pointer {
return nil, fmt.Errorf("expected a pointer to a struct, got %v", val.Kind())
}
if val.IsNil() {
return nil, errors.New("expected a pointer to a struct, got nil pointer")
}
valElem := val.Elem()
if valElem.Kind() != reflect.Struct {
return nil, fmt.Errorf("expected a pointer to a struct, got a pointer to %v", valElem.Kind())
}
typ := val.Type()
m := make(map[string]any)
for i := 0; i < val.NumMethod(); i++ {
k, v, err := marshalForMethod(typ.Method(i), val.Method(i))
if err != nil {
return nil, err
}
if k != "" {
m[k] = v
}
}
return m, nil
}View on GitHub (pinned to e9452d6e78)
Solutions
- Allocate the context struct before marshalling: pass &myContext{...} rather than a declared-but-nil pointer.
- Trace the call site producing the nil — a constructor returning (nil, err) whose error was ignored is the usual culprit; handle the error instead.
- If nil is a legitimate 'no data' state, guard the MarshalJSON call and emit an empty object or skip the row.
Example fix
// before
var imgCtx *imageContext
b, err := formatter.MarshalJSON(imgCtx)
// after
imgCtx := &imageContext{i: img, trunc: trunc}
b, err := formatter.MarshalJSON(imgCtx) When it happens
Trigger: Calling formatter.MarshalJSON(x) where x is a typed nil pointer, e.g. `var c *containerContext; formatter.MarshalJSON(c)` — typically from a formatter Context whose per-item context struct was never allocated before being handed to the JSON writer.
Common situations: Developing a custom formatter/context type in the docker CLI codebase and passing an unallocated pointer into the write path; refactors that change a formatter constructor to return nil on error while callers still marshal the result; unit tests feeding nil fixtures into formatter code.
Related errors
- unexpected hook response type:
- plugin candidate path cannot be empty
- unsupported type
- no output stream
AI-assisted analysis of docker/cli@e9452d6e78 (2026-08-01).
Data as JSON: /data/errors/451edf2afd065d96.json.
Report an issue: GitHub.