{"record":{"id":"3f4d3ee948dcd39d","repo":"googleapis/mcp-toolbox","slug":"error-creating-alloydb-instance-w","errorCode":null,"errorMessage":"error creating AlloyDB instance: %w","messagePattern":"error creating AlloyDB instance: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/alloydbadmin/alloydbadmin.go","lineNumber":201,"sourceCode":"\t}\n\n\tif instanceType == \"READ_POOL\" {\n\t\tinstance.ReadPoolConfig = &alloydbrestapi.ReadPoolConfig{\n\t\t\tNodeCount: int64(nodeCount),\n\t\t}\n\t}\n\n\tservice, err := s.getService(ctx, accessToken)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\turlString := fmt.Sprintf(\"projects/%s/locations/%s/clusters/%s\", project, location, cluster)\n\n\t// The Create API returns a long-running operation.\n\tresp, err := service.Projects.Locations.Clusters.Instances.Create(urlString, instance).InstanceId(instanceID).Do()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error creating AlloyDB instance: %w\", err)\n\t}\n\treturn resp, nil\n}\n\nfunc (s *Source) CreateUser(ctx context.Context, userType, password string, roles []string, accessToken, project, location, cluster, userID string) (any, error) {\n\t// Build the request body using the type-safe User struct.\n\tuser := &alloydbrestapi.User{\n\t\tUserType: userType,\n\t}\n\n\tif userType == \"ALLOYDB_BUILT_IN\" {\n\t\tuser.Password = password\n\t}\n\n\tif len(roles) > 0 {\n\t\tuser.DatabaseRoles = roles\n\t}\n","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/alloydbadmin/alloydbadmin.go#L183-L219","documentation":"This error wraps any failure returned by the AlloyDB Admin API's Instances.Create call, which submits a request to create a new instance inside an existing cluster. Because the underlying API returns a long-running operation, this error indicates the initial request itself failed (HTTP-level or request-construction error), not a later operation failure. The original Google API error is preserved via %w so callers can inspect it with errors.As/errors.Is.","triggerScenarios":"Calling Source.CreateInstance when the parent cluster resource path is wrong, the instance ID is invalid or already exists, the OAuth access token lacks the alloydb.admin scope, or the REST call to projects/*/locations/*/clusters/*/instances returns a non-2xx response.","commonSituations":"Typos in project/location/cluster names, creating an instance whose ID already exists in the cluster, expired or scope-limited access tokens, network egress blocked to the alloydb.googleapis.com endpoint, or instance fields violating API validation (e.g., invalid machine type).","solutions":["Verify project, location, and cluster names are correct and the cluster exists via GetCluster before creating the instance","Check the instance ID is unique in the cluster and matches AlloyDB naming rules (lowercase letters, numbers, hyphens)","Ensure the access token has the https://www.googleapis.com/auth/cloud-platform or alloydb.admin scope and is not expired","Inspect the wrapped error with errors.As on *googleapi.Error to read the exact HTTP status and message","Retry with exponential backoff only on 429/5xx responses; 409/400 responses need input correction"],"exampleFix":"// before\nresp, err := service.Projects.Locations.Clusters.Instances.Create(urlString, instance).InstanceId(instanceID).Do()\nif err != nil { return nil, err }\n// after\nif _, err := s.GetCluster(ctx, project, location, cluster, accessToken); err != nil {\n    return nil, fmt.Errorf(\"parent cluster check failed: %w\", err)\n}\nresp, err := service.Projects.Locations.Clusters.Instances.Create(urlString, instance).InstanceId(instanceID).Do()\nif err != nil {\n    var gerr *googleapi.Error\n    if errors.As(err, &gerr) && gerr.Code == 409 {\n        return nil, fmt.Errorf(\"instance %s already exists in %s: %w\", instanceID, cluster, err)\n    }\n    return nil, fmt.Errorf(\"error creating AlloyDB instance: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"// Go: validate inputs and parent cluster before CreateInstance\nif cluster == \"\" || instanceID == \"\" {\n    return fmt.Errorf(\"cluster and instanceID are required\")\n}\nif _, err := s.GetCluster(ctx, project, location, cluster, accessToken); err != nil {\n    return fmt.Errorf(\"parent cluster %s not reachable: %w\", cluster, err)\n}","typeGuard":"func IsGoogleAPIError(err error) (*googleapi.Error, bool) {\n    var gerr *googleapi.Error\n    ok := errors.As(err, &gerr)\n    return gerr, ok\n}","tryCatchPattern":"resp, err := s.CreateInstance(ctx, project, location, cluster, instance, accessToken, ...)\nif err != nil {\n    var gerr *googleapi.Error\n    if errors.As(err, &gerr) {\n        switch gerr.Code {\n        case 409:\n            return fmt.Errorf(\"instance already exists\")\n        case 403, 401:\n            return fmt.Errorf(\"auth failure, refresh token: %v\", gerr)\n        default:\n            return retryable(gerr.Code, err)\n        }\n    }\n    return err\n}","preventionTips":["Always check the parent cluster exists before creating an instance","Keep access tokens fresh and scoped to cloud-platform/alloydb.admin","Use deterministic, unique instance IDs to avoid 409 conflicts","Pre-validate instance config (machine type, network) against AlloyDB docs"],"tags":["gcp","alloydb","rest-api","authorization","http-error"],"backgroundTag":"gcp-api-request-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"}