{"record":{"id":"4e8d6f81debcd872","repo":"vitessio/vitess","slug":"can-t-get-v-v-4e8d6f","errorCode":null,"errorMessage":"can't get %v: %v","messagePattern":"can't get (.+?): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/api.go","lineNumber":62,"sourceCode":"func handleAPI(apiPath string, handlerFunc func(w http.ResponseWriter, r *http.Request) error) {\n\tservenv.HTTPHandleFunc(apiPrefix+apiPath, func(w http.ResponseWriter, r *http.Request) {\n\t\tdefer func() {\n\t\t\tif x := recover(); x != nil {\n\t\t\t\thttpErrorf(w, r, \"uncaught panic: %v\", x)\n\t\t\t}\n\t\t}()\n\t\tif err := handlerFunc(w, r); err != nil {\n\t\t\thttpErrorf(w, r, \"%v\", err)\n\t\t}\n\t})\n}\n\nfunc handleCollection(collection string, getFunc func(*http.Request) (any, error)) {\n\thandleAPI(collection+\"/\", func(w http.ResponseWriter, r *http.Request) error {\n\t\t// Get the requested object.\n\t\tobj, err := getFunc(r)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"can't get %v: %v\", collection, err)\n\t\t}\n\n\t\t// JSON encode response.\n\t\tdata, err := json.MarshalIndent(obj, \"\", \"  \")\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"cannot marshal data: %v\", err)\n\t\t}\n\t\tw.Header().Set(\"Content-Type\", jsonContentType)\n\t\tw.Write(data)\n\t\treturn nil\n\t})\n}\n\nfunc getItemPath(url string) string {\n\t// Strip API prefix.\n\tif !strings.HasPrefix(url, apiPrefix) {\n\t\treturn \"\"\n\t}","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/api.go#L44-L80","documentation":"The vtgate HTTP debug API's handleCollection wraps any error from the per-collection getFunc into `can't get <collection>: <err>`. The collection name (e.g. tablets, keyspaces) is preserved so you know which REST resource failed. The wrapped inner error carries the actual cause.","triggerScenarios":"Requesting a vtgate debug HTTP endpoint like /api/<collection>/ where getFunc fails — e.g. querying /api/tablets/ with a bad tablet filter or an unknown keyspace/cell, causing the underlying lookup to error.","commonSituations":"Scripts/curl against the vtgate debug API with mistyped collection values or keyspace/cell names; topology temporarily unreachable causing underlying getFunc errors.","solutions":["Read the wrapped inner error for the real cause and fix that (bad name, missing object).","Verify the collection path parameter (cell/keyspace/tablet) is correct.","Check topology connectivity if the underlying error indicates topo failure."],"exampleFix":"// before\ncurl http://vtgate:15001/api/keyspaces/wrongks/\n// after\ncurl http://vtgate:15001/api/keyspaces/commerce/","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"resp, err := http.Get(base + \"/api/keyspaces/\" + ks + \"/\")\nif err != nil || resp.StatusCode != 200 {\n    body, _ := io.ReadAll(resp.Body)\n    // body contains: can't get <collection>: <inner err>\n    log.Warn(\"vtgate API get failed\", \"body\", string(body))\n}","preventionTips":["Validate keyspace/cell names via vtctldclient before calling the HTTP API.","Check the wrapped inner error — it names the real cause.","Handle non-200 responses in scripts hitting the debug API."],"tags":["vtgate","http-api","debug-endpoint"],"backgroundTag":"http-request-failed","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}