{"record":{"id":"62b10e0debf2fe1a","repo":"geektutu/7days-golang","slug":"no-such-group-62b10e","errorCode":null,"errorMessage":"no such group: ","messagePattern":"no such group: ","errorType":"http","errorClass":null,"httpStatus":404,"severity":"error","filePath":"gee-cache/day5-multi-nodes/geecache/http.go","lineNumber":60,"sourceCode":"// ServeHTTP handle all http requests\nfunc (p *HTTPPool) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tif !strings.HasPrefix(r.URL.Path, p.basePath) {\n\t\tpanic(\"HTTPPool serving unexpected path: \" + r.URL.Path)\n\t}\n\tp.Log(\"%s %s\", r.Method, r.URL.Path)\n\t// /<basepath>/<groupname>/<key> required\n\tparts := strings.SplitN(r.URL.Path[len(p.basePath):], \"/\", 2)\n\tif len(parts) != 2 {\n\t\thttp.Error(w, \"bad request\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tgroupName := parts[0]\n\tkey := parts[1]\n\n\tgroup := GetGroup(groupName)\n\tif group == nil {\n\t\thttp.Error(w, \"no such group: \"+groupName, http.StatusNotFound)\n\t\treturn\n\t}\n\n\tview, err := group.Get(key)\n\tif err != nil {\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tw.Header().Set(\"Content-Type\", \"application/octet-stream\")\n\tw.Write(view.ByteSlice())\n}\n\n// Set updates the pool's list of peers.\nfunc (p *HTTPPool) Set(peers ...string) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tp.peers = consistenthash.New(defaultReplicas, nil)","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-cache/day5-multi-nodes/geecache/http.go#L42-L78","documentation":"day5 ServeHTTP found no group registered under the requested name (GetGroup returned nil) and responds 404 'no such group: <name>'. Registration via NewGroup is per-process; multi-node deployments must register groups on every node.","triggerScenarios":"GET with a group name absent from this node's registry; name typo; peer started without the group-registration bootstrap.","commonSituations":"Rolling out new nodes with stale config; inconsistent NewGroup calls across the cluster; renaming groups without updating all client URLs.","solutions":["Register the group with geecache.NewGroup on every node before serving traffic.","Cross-check the requested group name (exact, case-sensitive) with NewGroup arguments.","Drive group registration from shared config so all peers stay in sync.","Add a startup assertion/log that lists all registered groups per node."],"exampleFix":"// before: only node A registers the group\n// node B: no NewGroup -> 404 from B\n// after: identical bootstrap on all nodes\nfor _, cfg := range groupConfigs {\n    geecache.NewGroup(cfg.Name, cfg.Bytes, geecache.GetterFunc(cfg.Loader))\n}","handlingStrategy":"validation","validationCode":"// day5 multi-node: assert all configured groups exist on this node at startup\nfor _, name := range config.GroupNames {\n    if geecache.GetGroup(name) == nil {\n        log.Fatalf(\"group %q not registered on this node\", name)\n    }\n}","typeGuard":null,"tryCatchPattern":"// Go: surface 404 as a config error\nif resp.StatusCode == http.StatusNotFound {\n    return fmt.Errorf(\"group missing on peer %s: %s\", addr, body)\n}","preventionTips":["Use one shared bootstrap/config that registers all groups on every node.","Log registered groups at startup on each node for drift detection.","Match group names exactly (case-sensitive) between server and clients.","Alert on 404s from cache peers to catch nodes rolled out with stale config."],"tags":["http","cache","not-found","configuration","multi-node"],"backgroundTag":"cache-group-not-found","analyzedSha":"cf3644382101dc13e7fd92e8f5c66cabc51bcd3b","analyzedAt":"2026-09-03T18:31:24.087Z","contentChangedAt":"2026-09-03T18:31:24.087Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}