Skip to content

[Bug] nil pointer panic on API endpoints when request body is {} #108

Description

@CN-Antonio

Environment

  • HAMi WebUI: v1.2.0 (chart hami-webui-1.2.0)
  • HAMi Core: v2.9.0 (chart hami-2.9.0)
  • K3s: v1.36.2+k3s1 (2 nodes: control-plane + worker with GPU)
  • Prometheus: kube-prometheus-stack (existing external instance)
  • Deployment: Helm with externalPrometheus.enabled: true

Bug Description

Go backend (hami-webui-be-oss) panics with nil pointer dereference when API receives a request with empty body {}. The Vue WebUI frontend is unaffected because it always includes the filters field.

Root cause: Protobuf deserialization sets req.Filters to nil when the request body is {}. The service layer accesses filters.DeviceId etc. without nil checks.

Reproduction

# This triggers the panic (500 + nil pointer dereference):
curl -X POST http://<node-ip>:30324/v1/summary -d '{}'

# This works fine (Vue frontend sends this format):
curl -X POST http://<node-ip>:30324/v1/summary -d '{"filters":{}}'

The same issue affects /v1/nodes, /v1/gpus, /v1/containers, /v1/node, /v1/gpu, /v1/container.

Panic Trace

runtime error: invalid memory address or nil pointer dereference
vgpu/internal/service.(*NodeService).GetSummary(...)
    /src/internal/service/node.go:33

Fix

Added nil checks for req and req.Filters in all service methods. Also improved /readyz endpoint to return 503 when informers have not synced.

Files Changed

  • internal/service/node.go — nil guards on GetSummary, GetAllNodes, GetNode
  • internal/service/card.go — nil guards on GetAllGPUs, GetAllGPUTypes, GetGPU
  • internal/service/container.go — nil guard on GetAllContainers
  • internal/data/node.go — added Ready() flag set after informer sync + updateLocalNodes first run
  • internal/data/pod.go — added Ready() flag set after informer sync
  • internal/biz/node.go — added Ready() to NodeRepo interface
  • internal/biz/pod.go — added Ready() to PodRepo interface
  • internal/server/http.go/readyz returns 503 when informers not synced

Updated after further investigation: the original analysis incorrectly identified informer initialization failure as the root cause. The informers work correctly; the Vue frontend displays data normally. The actual issue is nil req.Filters on empty request bodies.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions