{"record":{"id":"7a786f4e9559e79a","repo":"googleapis/mcp-toolbox","slug":"operation-finished-with-error-but-could-not-marsha","errorCode":null,"errorMessage":"operation finished with error but could not marshal error object: %w","messagePattern":"operation finished with error but could not marshal error object: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/alloydbadmin/alloydbadmin.go","lineNumber":349,"sourceCode":"\t}\n\n\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}","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/alloydbadmin/alloydbadmin.go#L331-L367","documentation":"This error is thrown inside GetOperations when a long-running AlloyDB operation has finished with op.Error set, but the Go JSON marshal of that Google Rpc.Status error object itself failed. This is rare — it means the operation failed AND the error details could not be serialized (e.g., a value not JSON-marshalable was present in error details). It signals an internal serialization problem rather than the operation's own error content.","triggerScenarios":"GetOperations detects op.Done == true and op.Error != nil, calls json.Marshal(op.Error), and the marshal returns an error (e.g., unsupported types inside the Rpc.Status details Any fields).","commonSituations":"Unexpected or malformed Any payload types returned by the API in operation error details, custom/changed google-api-go-client versions with types the stdlib encoder cannot handle, or corrupted responses.","solutions":["Retry the GetOperations call — this is usually transient or response-corruption related","Update google-api-go-client and related Google SDK packages to the latest versions","Log the raw operation response from the API for debugging","Fall back to reporting the operation's Code and Message fields directly instead of full JSON marshal","If reproducible, capture the operation name and file an issue with the AlloyDB API team"],"exampleFix":"// before\nerrorBytes, err = json.Marshal(op.Error)\nif err != nil {\n    return nil, fmt.Errorf(\"operation finished with error but could not marshal error object: %w\", err)\n}\n// after\nerrorBytes, err = json.Marshal(op.Error)\nif err != nil {\n    // fall back to the plain fields instead of failing\n    return nil, fmt.Errorf(\"operation finished with error: code=%d message=%s (marshal failed: %v)\", op.Error.Code, op.Error.Message, err)\n}\nreturn nil, fmt.Errorf(\"operation finished with error: %s\", string(errorBytes))","handlingStrategy":"fallback","validationCode":null,"typeGuard":"func opErrorMarshalable(op *alloydb.Operation) bool {\n    if op == nil || op.Error == nil {\n        return false\n    }\n    _, err := json.Marshal(op.Error)\n    return err == nil\n}","tryCatchPattern":"op, err := s.GetOperations(ctx, project, location, opName, tmpl, delay, accessToken)\nif err != nil {\n    if strings.Contains(err.Error(), \"could not marshal error object\") {\n        // fallback: refetch raw operation or report op name for manual inspection\n        return nil, fmt.Errorf(\"operation %s failed but error details unavailable; check Cloud Logging\", opName)\n    }\n    return err\n}","preventionTips":["Keep google-api-go-client versions current so Rpc.Status marshals correctly","Log raw API responses when operations fail to aid debugging","Treat this as rare/transient and retry the operation fetch once","Have a fallback path that surfaces operation name instead of full details"],"tags":["alloydb","json","serialization","long-running-operation","gcp"],"backgroundTag":"json-marshal-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"}