{"record":{"id":"ff9ba2a59c63a7d1","repo":"googleapis/mcp-toolbox","slug":"api-returned-non-200-status-d-s","errorCode":null,"errorMessage":"API returned non-200 status: %d %s","messagePattern":"API returned non-200 status: (.+?) (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go","lineNumber":291,"sourceCode":"\t}\n\n\treq, err := http.NewRequest(\"POST\", url, bytes.NewBuffer(payloadBytes))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n\tfor k, v := range headers {\n\t\treq.Header.Set(k, v)\n\t}\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to send request: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tbody, _ := io.ReadAll(resp.Body)\n\t\treturn \"\", fmt.Errorf(\"API returned non-200 status: %d %s\", resp.StatusCode, string(body))\n\t}\n\n\tvar messages []map[string]any\n\tdecoder := json.NewDecoder(resp.Body)\n\tdataMsgIdx := -1\n\n\t// The response is a JSON array, so we read the opening bracket.\n\tif _, err := decoder.Token(); err != nil {\n\t\tif err == io.EOF {\n\t\t\treturn \"\", nil // Empty response is valid\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"error reading start of json array: %w\", err)\n\t}\n\n\tfor decoder.More() {\n\t\tvar rawMsg json.RawMessage\n\t\tif err := decoder.Decode(&rawMsg); err != nil {\n\t\t\tif err == io.EOF {","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go#L273-L309","documentation":"The Conversational Analytics `:chat` API responded with a status code other than 200; getStream reads the body and returns it inline so the caller can see the API's error message. Common statuses include 401/403 (auth/permissions), 404 (bad project/location), and 429/5xx (quota or server errors).","triggerScenarios":"Invoke on the tool when the GDA API rejects the request: missing cloudaicompanion.googleapis.com enablement, caller lacking the Conversational Analytics permission (e.g. roles/cloudaicompanion.user), wrong project/location in the URL, or exhausted quota.","commonSituations":"Service account without the required Conversational Analytics IAM role; API not enabled in the project; incorrect location (e.g. region mismatch with the BigQuery dataset); quota exceeded after heavy usage; VPC-SC perimeter rejection.","solutions":["Read the status and body in the error: fix the specific cause reported by the API (permission denied, not found, etc.).","Enable the Conversational Analytics API (`gcloud services enable cloudaicompanion.googleapis.com`) in the project.","Grant the caller (service account/user) the required IAM role (e.g. Cloud AI Companion User) on the project.","Verify the BigQuery source's project and location match the datasets being referenced.","For 429/5xx, retry with exponential backoff; for 401, refresh credentials."],"exampleFix":"// before: 403 PERMISSION_DENIED\n//   gcloud projects add-iam-policy-binding MY_PROJECT \\\n//     --member=\"serviceAccount:sa@project.iam.gserviceaccount.com\" --role=\"roles/viewer\"\n// after\n//   gcloud projects add-iam-policy-binding MY_PROJECT \\\n//     --member=\"serviceAccount:sa@project.iam.gserviceaccount.com\" --role=\"roles/cloudaicompanion.user\"","handlingStrategy":"try-catch","validationCode":"cl, err := bigquery.NewClient(ctx, projectID)\nif err != nil { return err }\n_, err = cl.Dataset(datasetID).Metadata(ctx) // confirms project/dataset access\nif err != nil { return fmt.Errorf(\"dataset inaccessible: %w\", err) }","typeGuard":null,"tryCatchPattern":"result, err := tool.Invoke(ctx, params)\nif err != nil && strings.Contains(err.Error(), \"non-200 status\") {\n    if strings.Contains(err.Error(), \"403\") {\n        return fmt.Errorf(\"grant roles/cloudaicompanion.user and enable cloudaicompanion.googleapis.com: %w\", err)\n    }\n    return err\n}","preventionTips":["Enable cloudaicompanion.googleapis.com in the target project before using the tool.","Grant the caller the Conversational Analytics IAM role.","Keep the source's project/location consistent with referenced datasets.","Implement backoff on 429/5xx statuses."],"tags":["http","google-cloud","api-error","bigquery"],"backgroundTag":"api-non-200-status","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}