{"record":{"id":"e6ff9d822c0853be","repo":"geektutu/7days-golang","slug":"key-is-required-e6ff9d","errorCode":null,"errorMessage":"key is required","messagePattern":"key is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gee-cache/day4-consistent-hash/geecache/geecache.go","lineNumber":62,"sourceCode":"\t\tmainCache: cache{cacheBytes: cacheBytes},\n\t}\n\tgroups[name] = g\n\treturn g\n}\n\n// GetGroup returns the named group previously created with NewGroup, or\n// nil if there's no such group.\nfunc GetGroup(name string) *Group {\n\tmu.RLock()\n\tg := groups[name]\n\tmu.RUnlock()\n\treturn g\n}\n\n// Get value for a key from cache\nfunc (g *Group) Get(key string) (ByteView, error) {\n\tif key == \"\" {\n\t\treturn ByteView{}, fmt.Errorf(\"key is required\")\n\t}\n\n\tif v, ok := g.mainCache.get(key); ok {\n\t\tlog.Println(\"[GeeCache] hit\")\n\t\treturn v, nil\n\t}\n\n\treturn g.load(key)\n}\n\nfunc (g *Group) load(key string) (value ByteView, err error) {\n\treturn g.getLocally(key)\n}\n\nfunc (g *Group) getLocally(key string) (ByteView, error) {\n\tbytes, err := g.getter.Get(key)\n\tif err != nil {\n\t\treturn ByteView{}, err","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-cache/day4-consistent-hash/geecache/geecache.go#L44-L80","documentation":"Same guard in day4 (consistent-hash peers): Group.Get rejects an empty key with 'key is required' before local lookup or consistent-hash peer selection. Empty keys would otherwise be hashed and possibly routed to a peer pointlessly.","triggerScenarios":"Calling group.Get(\"\") directly, or an HTTP cache request with a missing/empty key parameter, or an upstream caller forwarding an empty string from user input into the cache API.","commonSituations":"Missing query parameter in requests proxied through the consistent-hash peer pool; buggy URL builders; tests exercising the validation path.","solutions":["Ensure the key query parameter is present and non-empty on all cache requests","Validate the key before calling group.Get in application code","Return a 400 response for empty keys at the HTTP boundary","Check consistent-hash peer URL construction preserves the key parameter"],"exampleFix":"// before\nkey := r.URL.Query().Get(\"key\")\nv, err := group.Get(key)\n// after\nkey := r.URL.Query().Get(\"key\")\nif key == \"\" { http.Error(w, \"key is required\", http.StatusBadRequest); return }\nv, err := group.Get(key)","handlingStrategy":"validation","validationCode":"func getFromCache(g *geecache.Group, key string) (geecache.ByteView, error) {\n    if strings.TrimSpace(key) == \"\" {\n        return geecache.ByteView{}, errors.New(\"cache: key must be non-empty\")\n    }\n    return g.Get(key)\n}","typeGuard":null,"tryCatchPattern":"v, err := group.Get(key)\nif err != nil {\n    if err.Error() == \"key is required\" {\n        http.Error(w, \"missing cache key\", http.StatusBadRequest)\n        return\n    }\n    http.Error(w, err.Error(), http.StatusInternalServerError)\n}","preventionTips":["Guard empty keys before they enter the consistent-hash routing layer","Check the key query parameter in the peer-aware HTTP handler","Cover the empty-key path in unit tests for both Group.Get and ServeHTTP"],"tags":["go","cache","validation","consistent-hashing"],"backgroundTag":"empty-cache-key","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"}