{"record":{"id":"c55ef505b5a64503","repo":"geektutu/7days-golang","slug":"key-is-required","errorCode":null,"errorMessage":"key is required","messagePattern":"key is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gee-cache/day2-single-node/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/day2-single-node/geecache/geecache.go#L44-L80","documentation":"Group.Get in the day2 single-node geecache validates that the requested key is non-empty before consulting the cache; an empty key returns this error immediately. It prevents cache pollution/ambiguity from blank keys.","triggerScenarios":"Calling group.Get(\"\") directly, or an HTTP request reaching the cache server with an empty or missing 'key' query parameter (e.g. GET /_geecache/ or /_geecache/?key=).","commonSituations":"Misconfigured URL construction that drops the query string; a proxy stripping empty query params; tests or callers not validating user input before hitting the cache.","solutions":["Check that the HTTP request URL includes ?key=<name> (e.g. /_geecache/scores?key=math)","Reject empty keys on the caller side before calling group.Get","Fix URL-building code that omits the query parameter"],"exampleFix":"// before\nresp, _ := http.Get(baseURL + \"/_geecache/scores?key=\" + key) // key may be \"\"\n// after\nif key == \"\" { return nil, errors.New(\"missing key\") }\nresp, _ := http.Get(baseURL + \"/_geecache/scores?key=\" + url.QueryEscape(key))","handlingStrategy":"validation","validationCode":"func cacheGet(g *geecache.Group, key string) (geecache.ByteView, error) {\n    if key == \"\" {\n        return geecache.ByteView{}, errors.New(\"cache: empty key\")\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 key\", http.StatusBadRequest)\n        return\n    }\n    http.Error(w, err.Error(), http.StatusInternalServerError)\n}","preventionTips":["Always validate the key query parameter at the HTTP handler boundary","Use url.Values / r.URL.Query() and explicitly check presence and non-emptiness","Reject blank user input upstream before it reaches the cache layer"],"tags":["go","cache","validation","input"],"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"}