{"record":{"id":"47c10ba8a8a5365b","repo":"pulumi/pulumi","slug":"exporting-audit-logs-w","errorCode":null,"errorMessage":"exporting audit logs: %w","messagePattern":"exporting audit logs: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/backend/httpstate/client/client.go","lineNumber":1796,"sourceCode":"\t}\n\tqueryObj := struct {\n\t\tFormat            string `url:\"format,omitempty\"`\n\t\tEventType         string `url:\"eventType,omitempty\"`\n\t\tUser              string `url:\"user,omitempty\"`\n\t\tStartTime         string `url:\"startTime,omitempty\"`\n\t\tContinuationToken string `url:\"continuationToken,omitempty\"`\n\t}{\n\t\tFormat:            format,\n\t\tEventType:         opts.EventType,\n\t\tUser:              opts.User,\n\t\tStartTime:         opts.StartTime,\n\t\tContinuationToken: opts.ContinuationToken,\n\t}\n\n\tvar body io.ReadCloser\n\tpath := fmt.Sprintf(\"/api/orgs/%s/auditlogs/export\", url.PathEscape(orgName))\n\tif err := pc.restCall(ctx, http.MethodGet, path, queryObj, nil, &body); err != nil {\n\t\treturn nil, fmt.Errorf(\"exporting audit logs: %w\", err)\n\t}\n\treturn body, nil\n}\n\n// UpdateOrganizationMember updates the role assignment of a member within\n// the given organization. Wraps the `UpdateOrganizationMember` Pulumi Cloud\n// REST endpoint (PATCH /api/orgs/{orgName}/members/{userLogin}). Only the\n// non-nil fields of req are sent; the service interprets omitted fields as\n// \"leave unchanged\".\nfunc (pc *Client) UpdateOrganizationMember(\n\tctx context.Context, orgName, userLogin string, req apitype.UpdateOrganizationMemberRequest,\n) error {\n\tpath := fmt.Sprintf(\"/api/orgs/%s/members/%s\", url.PathEscape(orgName), url.PathEscape(userLogin))\n\tif err := pc.restCall(ctx, http.MethodPatch, path, nil, req, nil); err != nil {\n\t\treturn fmt.Errorf(\"updating organization member: %w\", err)\n\t}\n\treturn nil\n}","sourceCodeStart":1778,"sourceCodeEnd":1814,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/pkg/backend/httpstate/client/client.go#L1778-L1814","documentation":"This error is returned by Client.ExportAuditLogs when the GET /api/orgs/{orgName}/auditlogs/export REST call fails. On success the server returns a streaming body (io.ReadCloser); this error wraps any failure before or during establishing that export, preserving the underlying restCall error via %w.","triggerScenarios":"Calling ExportAuditLogs(ctx, orgName, opts) when the export request fails: missing audit-log permissions (403), invalid token (401), unknown org (404), invalid date range or continuation token, or network failure before the response body is opened.","commonSituations":"Compliance automation exporting audit logs with a token whose role lacks audit access; very large exports timing out at the proxy; org slug mismatch after a rename.","solutions":["Verify the token's role can export audit logs (Admin/audit permissions on the organization).","Validate the org slug and the date range/ContinuationToken fields in ExportAuditLogsOptions.","Retry transient failures with backoff; for large ranges, narrow the export window.","Unwrap the error to inspect the HTTP status returned by the service."],"exampleFix":"// before\nbody, err := client.ExportAuditLogs(ctx, orgName, opts)\nif err != nil { return err }\n// after\nbody, err := client.ExportAuditLogs(ctx, orgName, opts)\nif err != nil {\n    return fmt.Errorf(\"cannot export audit logs for %q: %w\", orgName, err)\n}\ndefer body.Close()","handlingStrategy":"retry","validationCode":"if orgName == \"\" {\n    return errors.New(\"organization name is required\")\n}\nif os.Getenv(\"PULUMI_ACCESS_TOKEN\") == \"\" {\n    return errors.New(\"PULUMI_ACCESS_TOKEN is not set\")\n}","typeGuard":"func isPermissionErr(err error) bool {\n    var restErr *apitype.ErrorResponse\n    return errors.As(err, &restErr) && restErr.Code == http.StatusForbidden\n}","tryCatchPattern":"var body io.ReadCloser\nvar err error\nfor attempt := 0; attempt < 3; attempt++ {\n    body, err = client.ExportAuditLogs(ctx, orgName, opts)\n    if err == nil {\n        break\n    }\n    var restErr *apitype.ErrorResponse\n    if errors.As(err, &restErr) && restErr.Code < 500 {\n        break // client error: do not retry\n    }\n    time.Sleep(time.Duration(1<<attempt) * time.Second)\n}\nif err != nil {\n    return fmt.Errorf(\"exporting audit logs for %q: %w\", orgName, err)\n}\ndefer body.Close()","preventionTips":["Confirm export permission on the service account before scheduling jobs.","Narrow the export date window to avoid proxy/gateway timeouts.","Always Close the returned body on success.","Handle 404 as org-not-found, not a transient fault."],"tags":["http","pulumi-cloud","audit-logs","export"],"backgroundTag":"http-request-failed","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}