{"record":{"id":"248dd6be917c1159","repo":"rqlite/rqlite","slug":"query-not-specified","errorCode":null,"errorMessage":"query not specified","messagePattern":"query not specified","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"http/service.go","lineNumber":604,"sourceCode":"// handleSQLAnalyze handles requests to analyze and show SQL rewriting.\nfunc (s *Service) handleSQLAnalyze(w http.ResponseWriter, r *http.Request, qp QueryParams) {\n\tw.Header().Set(\"Content-Type\", \"application/json; charset=utf-8\")\n\n\tif !s.CheckRequestPerm(r, auth.PermQuery) {\n\t\tw.WriteHeader(http.StatusUnauthorized)\n\t\treturn\n\t}\n\n\tif r.Method != \"GET\" && r.Method != \"POST\" {\n\t\tw.WriteHeader(http.StatusMethodNotAllowed)\n\t\treturn\n\t}\n\n\tvar stmts []*proto.Statement\n\tif r.Method == \"GET\" {\n\t\tq := qp.Query()\n\t\tif q == \"\" {\n\t\t\thttp.Error(w, \"query not specified\", http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\t\tstmts = []*proto.Statement{{Sql: q}}\n\t} else {\n\t\tvar err error\n\t\tstmts, err = ParseRequest(r.Body)\n\t\tif err != nil {\n\t\t\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\t}\n\n\tanalyzeStmt := func(sqlStr string, rwRand, rwTime bool) (res sqlAnalyzeStmtResult, retErr error) {\n\t\tdefer func() {\n\t\t\tif r := recover(); r != nil {\n\t\t\t\tretErr = fmt.Errorf(\"panic during SQL analysis: %v\", r)\n\t\t\t}\n\t\t}()","sourceCodeStart":586,"sourceCodeEnd":622,"githubUrl":"https://github.com/rqlite/rqlite/blob/7586a4d1bdbd9a5a80021664c5a863cd850adb60/http/service.go#L586-L622","documentation":"Raised by the /db/analyze handler when the request is a GET and the `q` (query) URL parameter is empty or absent. The analyze endpoint needs at least one SQL statement to inspect, so the request is rejected with 400 before any parsing happens.","triggerScenarios":"GET /db/analyze without `?q=SELECT...`, or with `?q=` empty, or with the SQL supplied in a POST-style body while still issuing a GET request.","commonSituations":"Copy-pasting the endpoint URL without appending the q parameter; URL-encoding issues dropping the parameter; tools that strip empty query params; confusing /db/analyze (needs q) with /db/query behaviors.","solutions":["Append the SQL to analyze as the q parameter: GET /db/analyze?q=SELECT+RANDOM().","URL-encode the SQL statement in the q parameter.","Alternatively use POST with a JSON body containing the statements array."],"exampleFix":"// before\ncurl 'http://localhost:4001/db/analyze'\n// 400: query not specified\n// after\ncurl 'http://localhost:4001/db/analyze?q=SELECT%20RANDOM()'","handlingStrategy":"validation","validationCode":"// JS: validate before calling\nif (!q || !q.trim()) throw new Error('q query parameter is required for /db/analyze');\nconst url = `http://host:4001/db/analyze?q=${encodeURIComponent(q)}`;","typeGuard":"function hasQuery(q) { return typeof q === 'string' && q.trim().length > 0 }","tryCatchPattern":"const res = await fetch(url)\nif (res.status === 400 && (await res.text()).includes('query not specified')) {\n  console.error('Supply ?q=<sql> to /db/analyze')\n}","preventionTips":["Always build /db/analyze URLs through a helper that encodes and appends q.","Assert q is non-empty in unit tests for client code paths.","Prefer POST with a JSON statements body for programmatic use to avoid URL param pitfalls."],"tags":["http","bad-request","missing-parameter","query"],"backgroundTag":"missing-required-argument","analyzedSha":"7586a4d1bdbd9a5a80021664c5a863cd850adb60","analyzedAt":"2026-09-03T07:03:02.260Z","contentChangedAt":"2026-09-03T07:03:02.260Z","schemaVersion":2},"datasetVersion":"2026-09-10T12:17:11.382Z"}