{"record":{"id":"06d58395788c0ef6","repo":"googleapis/mcp-toolbox","slug":"operation-finished-with-error-s","errorCode":null,"errorMessage":"operation finished with error: %s","messagePattern":"operation finished with error: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/alloydbadmin/alloydbadmin.go","lineNumber":351,"sourceCode":"\tservice, err := s.getService(ctx, accessToken)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tname := fmt.Sprintf(\"projects/%s/locations/%s/operations/%s\", project, location, operation)\n\n\top, err := service.Projects.Locations.Operations.Get(name).Do()\n\tif err != nil {\n\t\tlogger.DebugContext(ctx, fmt.Sprintf(\"error getting operation: %s, retrying in %v\\n\", err, delay))\n\t} else {\n\t\tif op.Done {\n\t\t\tif op.Error != nil {\n\t\t\t\tvar errorBytes []byte\n\t\t\t\terrorBytes, err = json.Marshal(op.Error)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"operation finished with error but could not marshal error object: %w\", err)\n\t\t\t\t}\n\t\t\t\treturn nil, fmt.Errorf(\"operation finished with error: %s\", string(errorBytes))\n\t\t\t}\n\n\t\t\tvar opBytes []byte\n\t\t\topBytes, err = op.MarshalJSON()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"could not marshal operation: %w\", err)\n\t\t\t}\n\n\t\t\tif op.Response != nil {\n\t\t\t\tvar responseData map[string]any\n\t\t\t\tif err := json.Unmarshal(op.Response, &responseData); err == nil && responseData != nil {\n\t\t\t\t\tif msg, ok := generateAlloyDBConnectionMessage(responseData, connectionMessageTemplate); ok {\n\t\t\t\t\t\treturn msg, nil\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar result any","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/alloydbadmin/alloydbadmin.go#L333-L369","documentation":"This error is returned by GetOperations when a polled AlloyDB long-running operation has completed unsuccessfully: op.Done is true and op.Error is non-nil. The Google Rpc.Status object (HTTP status code and error message from the failed operation) is JSON-marshaled and embedded in this message, so the full failure reason is in the error text. It represents the authoritative failure of a create/delete/patch operation, not a client-side problem.","triggerScenarios":"Polling an operation via Projects.Locations.Operations.Get whose target action failed server-side — e.g., instance creation rejected due to quota exhaustion, invalid configuration, permission denial, or resource conflicts — and the API returned Done=true with an Error status.","commonSituations":"Exceeded AlloyDB quota or regional capacity, invalid instance settings (machine type, network), permission revoked between request start and completion, project billing issues, and conflicts like a duplicate resource created concurrently.","solutions":["Parse the JSON payload in the message (fields code and message) to read the API's failure reason","If the code indicates quota (e.g., 8/RESOURCE_EXHAUSTED or 429), check AlloyDB quotas in the Cloud Console and request an increase","If permissions-related, verify the caller's IAM roles include roles/alloydb.admin before re-running the operation","Fix the underlying configuration (machine type, network, region) and resubmit the create/update request","Check Cloud Logging for the operation's detailed server-side logs for root cause"],"exampleFix":"// before\nif op.Error != nil {\n    errorBytes, _ := json.Marshal(op.Error)\n    return nil, fmt.Errorf(\"operation finished with error: %s\", string(errorBytes))\n}\n// after\nif op.Error != nil {\n    var rpcStatus struct {\n        Code    int    `json:\"code\"`\n        Message string `json:\"message\"`\n    }\n    if b, err := json.Marshal(op.Error); err == nil && json.Unmarshal(b, &rpcStatus) == nil {\n        return nil, fmt.Errorf(\"operation failed (gRPC code %d): %s\", rpcStatus.Code, rpcStatus.Message)\n    }\n    errorBytes, _ := json.Marshal(op.Error)\n    return nil, fmt.Errorf(\"operation finished with error: %s\", string(errorBytes))\n}","handlingStrategy":"try-catch","validationCode":"// Go: pre-flight checks before starting/polling an operation\nif err := checkQuotaAndBilling(project); err != nil {\n    return fmt.Errorf(\"preflight failed: %w\", err)\n}\n// ensure config (machine type, region, network) is valid before submitting","typeGuard":"func ParseOperationFailure(err error) (grpcCode int, message string, ok bool) {\n    const prefix = \"operation finished with error: \"\n    msg := err.Error()\n    i := strings.Index(msg, prefix)\n    if i < 0 {\n        return 0, \"\", false\n    }\n    var st struct {\n        Code    int    `json:\"code\"`\n        Message string `json:\"message\"`\n    }\n    if json.Unmarshal([]byte(msg[i+len(prefix):]), &st) != nil {\n        return 0, \"\", false\n    }\n    return st.Code, st.Message, true\n}","tryCatchPattern":"_, err := s.GetOperations(ctx, project, location, opName, tmpl, pollDelay, accessToken)\nif err != nil {\n    if code, msg, ok := ParseOperationFailure(err); ok {\n        switch code {\n        case 8: // RESOURCE_EXHAUSTED\n            return fmt.Errorf(\"quota exceeded: %s — request quota increase\", msg)\n        case 7: // PERMISSION_DENIED\n            return fmt.Errorf(\"IAM permission missing: %s\", msg)\n        default:\n            return fmt.Errorf(\"operation failed: %s\", msg)\n        }\n    }\n    return err\n}","preventionTips":["Check AlloyDB quotas and billing status before launching instance operations","Validate instance configuration against API docs before submitting","Parse the JSON in the error message to react to specific gRPC codes","Watch Cloud Logging for server-side root causes of failed operations"],"tags":["alloydb","long-running-operation","gcp","quota","server-error"],"backgroundTag":"long-running-operation-failed","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"}