{"record":{"id":"03265b90545e60b3","repo":"vitessio/vitess","slug":"cells-can-only-be-listed-not-retrieved","errorCode":null,"errorMessage":"cells can only be listed, not retrieved","messagePattern":"cells can only be listed, not retrieved","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctld/api.go","lineNumber":189,"sourceCode":"\treturn parts[1]\n}\n\nfunc unmarshalRequest(r *http.Request, v any) error {\n\tdata, err := io.ReadAll(r.Body)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn json.Unmarshal(data, v)\n}\n\nfunc initAPI(ctx context.Context, ts *topo.Server, actions *ActionRepository) {\n\ttabletHealthCache := newTabletHealthCache(ts)\n\ttmClient := tmclient.NewTabletManagerClient()\n\n\t// Cells\n\thandleCollection(\"cells\", func(r *http.Request) (any, error) {\n\t\tif getItemPath(r.URL.Path) != \"\" {\n\t\t\treturn nil, errors.New(\"cells can only be listed, not retrieved\")\n\t\t}\n\t\treturn ts.GetKnownCells(ctx)\n\t})\n\n\t// Keyspaces\n\thandleCollection(\"keyspaces\", func(r *http.Request) (any, error) {\n\t\tkeyspace := getItemPath(r.URL.Path)\n\t\tswitch r.Method {\n\t\tcase \"GET\":\n\t\t\t// List all keyspaces.\n\t\t\tif keyspace == \"\" {\n\t\t\t\treturn ts.GetKeyspaces(ctx)\n\t\t\t}\n\t\t\t// Get the keyspace record.\n\t\t\tk, err := ts.GetKeyspace(ctx, keyspace)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctld/api.go#L171-L207","documentation":"This error comes from the vtctld HTTP API collection handler for /api/cells/. The cells endpoint is a collection (list-only): when the request path tries to GET an individual cell item (a non-empty item path after 'cells'), the handler returns this error instead of attempting a per-cell lookup, because no per-cell retrieval is implemented.","triggerScenarios":"Issuing an HTTP GET to /api/cells/<name> (or any path with a non-empty item segment after 'cells') on the vtctld web API; e.g. curl http://vtctld:15000/api/cells/zone1.","commonSituations":"Scripts converted from vtctl 'GetCellInfo' style lookups hitting the HTTP API; clients assuming REST-style single-resource GET exists for cells; typos leaving a trailing path segment.","solutions":["List all cells instead: GET /api/cells (no trailing path).","For a specific cell, fetch the list and filter client-side, or use vtctldclient GetCellInfo.","Use the gRPC vtctlservice (GetCellInfo RPC) if per-cell data is needed programmatically."],"exampleFix":"// before\ncurl http://localhost:15000/api/cells/zone1\n// after\ncurl http://localhost:15000/api/cells   # list only","handlingStrategy":"validation","validationCode":"if strings.HasSuffix(req.URL.Path, \"/api/cells/\") || strings.Contains(strings.TrimPrefix(req.URL.Path, \"/api/cells/\"), \"/\") {\n    return fmt.Errorf(\"/api/cells is list-only; do not request an individual cell\")\n}","typeGuard":null,"tryCatchPattern":"resp, err := http.Get(base + \"/api/cells/zone1\")\n// handler returns 4xx with message 'cells can only be listed, not retrieved'\n// switch to the list endpoint and filter locally\nif err != nil || resp.StatusCode != http.StatusOK { /* use /api/cells */ }","preventionTips":["Always use GET /api/cells and filter the list client-side.","Use the gRPC vtctlservice GetCellInfo for per-cell data."],"tags":["http-api","vtctld","cells","rest"],"backgroundTag":"collection-endpoint-item-get","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}