{"record":{"id":"12f7714f24f3ea5a","repo":"geektutu/7days-golang","slug":"key-is-required-12f771","errorCode":null,"errorMessage":"key is required","messagePattern":"key is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gee-cache/day3-http-server/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/day3-http-server/geecache/geecache.go#L44-L80","documentation":"Identical to the day2 check: Group.Get in day3 (HTTP server) returns 'key is required' when Get is called with an empty string, before any cache lookup or peer fetch. The HTTP handler passes the request's key parameter straight through, so blank keys surface this error.","triggerScenarios":"group.Get(\"\") in application code, or requests like GET /api/?key= / GET /api/ where the key query parameter is missing (ServeHTTP would also return http.StatusBadRequest for missing query param — the error text appears when Get is invoked with \"\").","commonSituations":"Clients hitting the cache API without the key parameter; URL encoding mistakes; empty form values forwarded as the key; test code calling Get with \"\" to assert validation.","solutions":["Always send a non-empty key query parameter to the cache HTTP endpoint","Validate/sanitize inputs before constructing the cache request URL","Handle the returned error and return 400 to the end client instead of a 500","Add a client-side check: if key == \"\" skip the call"],"exampleFix":"// before\ngroup.Get(r.URL.Query().Get(\"key\")) // may be \"\"\n// after\nkey := r.URL.Query().Get(\"key\")\nif key == \"\" { http.Error(w, \"key is required\", http.StatusBadRequest); return }\ngroup.Get(key)","handlingStrategy":"validation","validationCode":"key := r.URL.Query().Get(\"key\")\nif key == \"\" {\n    http.Error(w, \"key is required\", http.StatusBadRequest)\n    return\n}\nv, err := group.Get(key)","typeGuard":null,"tryCatchPattern":"v, err := group.Get(key)\nif err != nil {\n    if err.Error() == \"key is required\" {\n        w.WriteHeader(http.StatusBadRequest)\n        return\n    }\n    w.WriteHeader(http.StatusInternalServerError)\n}","preventionTips":["Validate query parameters in ServeHTTP before calling Group.Get","Add a test asserting 400 for GET /_geecache/ without a key","Escape and check the key with url.QueryEscape when building client URLs"],"tags":["go","cache","validation","http"],"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"}