{"record":{"id":"7c1e0c72c929a163","repo":"hasura/graphql-engine","slug":"citus-run-sql-api-request-failed-d","errorCode":null,"errorMessage":"citus_run_sql api request failed %d","messagePattern":"citus_run_sql api request failed (.+?)","errorType":"http","errorClass":"errors.Error","httpStatus":null,"severity":"error","filePath":"cli/internal/hasura/sourceops/citus/run_sql.go","lineNumber":35,"sourceCode":"\t\tType: \"citus_run_sql\",\n\t\tArgs: input,\n\t}\n\n\tb := new(bytes.Buffer)\n\n\tresp, err := d.send(body, b)\n\tif err != nil {\n\t\treturn nil, errors.E(op, err)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tif b.Len() > 0 {\n\t\t\treturn nil, errors.E(op, errors.KindHasuraAPI, b.String())\n\t\t} else {\n\t\t\treturn nil, errors.E(\n\t\t\t\top,\n\t\t\t\terrors.KindHasuraAPI,\n\t\t\t\tfmt.Errorf(\"citus_run_sql api request failed %d\", resp.StatusCode),\n\t\t\t)\n\t\t}\n\t}\n\n\to := new(hasura.CitusRunSQLOutput)\n\tif err = json.NewDecoder(b).Decode(o); err != nil {\n\t\treturn nil, errors.E(op, err)\n\t}\n\n\treturn o, nil\n}\n","sourceCodeStart":17,"sourceCodeEnd":47,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/cli/internal/hasura/sourceops/citus/run_sql.go#L17-L47","documentation":"CitusRunSQL returns this error when the Hasura server answers the citus_run_sql metadata API call with a non-200 status and an empty response body. Since there is no body text to relay, only the numeric HTTP status is reported. The error carries errors.KindHasuraAPI, indicating the CLI's request was delivered but the server refused to execute the SQL via the Citus source.","triggerScenarios":"Running 'hasura migrate apply' or another flow that calls citus_run_sql against a server that responds 401/403 (auth), 404 (citus source kind or endpoint missing), or 500 with empty body (target Citus/Postgres database unreachable, bad connection string, or metadata inconsistency).","commonSituations":"Citius source configured with an unreachable database URL, expired DB credentials, wrong admin secret, Hasura server version lacking the citus plugin, or an infrastructure layer (proxy, service mesh) that discards error bodies.","solutions":["Decode the embedded HTTP status: 401/403 → verify admin secret; 404 → confirm citus source support; 5xx → check Hasura and Citus database logs","Validate the Citus database connection directly (psql with the same URL) to rule out network/credential issues","Run the CLI with --debug to see the raw HTTP exchange","Ensure metadata for the citus source is consistent (POST /v1/metadata with export/inconsistent check)","Align CLI and server versions"],"exampleFix":"// before\nout, err := c.CitusRunSQL(args)\nif err != nil { return err }\n\n// after\nout, err := c.CitusRunSQL(args)\nif err != nil {\n  if strings.Contains(err.Error(), \"citus_run_sql api request failed\") {\n    return fmt.Errorf(\"citus_run_sql rejected; inspect server logs: %w\", err)\n  }\n  return err\n}","handlingStrategy":"try-catch","validationCode":"// Check source health before running migrations\n// POST /v1/metadata {\"type\":\"export_metadata\"} → assert a kind:\"citus\" source with a reachable URL exists","typeGuard":"func isEmptyBodyAPIError(err error) bool {\n  return err != nil && strings.Contains(err.Error(), \"api request failed\")\n}","tryCatchPattern":"out, err := c.CitusRunSQL(args)\nif err != nil {\n  if isEmptyBodyAPIError(err) {\n    return diagnoseFromStatus(err) // 401 vs 404 vs 5xx; then read server logs\n  }\n  return err\n}","preventionTips":["Test the Citus connection string with psql before configuring the source","Automate metadata consistency checks in CI before migrate apply","Version-pin CLI and server together"],"tags":["hasura","citus","run-sql","http-status","api-error","go"],"backgroundTag":"hasura-metadata-api-error","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}