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.
Environment
hami-webui-1.2.0)hami-2.9.0)externalPrometheus.enabled: trueBug Description
Go backend (
hami-webui-be-oss) panics withnil pointer dereferencewhen API receives a request with empty body{}. The Vue WebUI frontend is unaffected because it always includes thefiltersfield.Root cause: Protobuf deserialization sets
req.Filtersto nil when the request body is{}. The service layer accessesfilters.DeviceIdetc. without nil checks.Reproduction
The same issue affects
/v1/nodes,/v1/gpus,/v1/containers,/v1/node,/v1/gpu,/v1/container.Panic Trace
Fix
Added nil checks for
reqandreq.Filtersin all service methods. Also improved/readyzendpoint to return 503 when informers have not synced.Files Changed
internal/service/node.go— nil guards onGetSummary,GetAllNodes,GetNodeinternal/service/card.go— nil guards onGetAllGPUs,GetAllGPUTypes,GetGPUinternal/service/container.go— nil guard onGetAllContainersinternal/data/node.go— addedReady()flag set after informer sync +updateLocalNodesfirst runinternal/data/pod.go— addedReady()flag set after informer syncinternal/biz/node.go— addedReady()toNodeRepointerfaceinternal/biz/pod.go— addedReady()toPodRepointerfaceinternal/server/http.go—/readyzreturns 503 when informers not syncedUpdated 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.Filterson empty request bodies.