{"record":{"id":"6de1ec7f9f2bfe24","repo":"pulumi/pulumi","slug":"listing-audit-logs-w","errorCode":null,"errorMessage":"listing audit logs: %w","messagePattern":"listing audit logs: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/backend/httpstate/client/client.go","lineNumber":1741,"sourceCode":"func (pc *Client) ListAuditLogs(\n\tctx context.Context, orgName string, opts ListAuditLogsOptions,\n) (apitype.ListAuditLogEventsResponse, error) {\n\tqueryObj := struct {\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\tEventType:         opts.EventType,\n\t\tUser:              opts.User,\n\t\tStartTime:         opts.StartTime,\n\t\tContinuationToken: opts.ContinuationToken,\n\t}\n\n\tvar resp apitype.ListAuditLogEventsResponse\n\tpath := fmt.Sprintf(\"/api/orgs/%s/auditlogs\", url.PathEscape(orgName))\n\tif err := pc.restCall(ctx, http.MethodGet, path, queryObj, nil, &resp); err != nil {\n\t\treturn resp, fmt.Errorf(\"listing audit logs: %w\", err)\n\t}\n\treturn resp, nil\n}\n\n// ExportAuditLogsOptions are the optional query parameters accepted by\n// ExportAuditLogs. Empty fields are omitted from the request and let the\n// service apply its own defaults.\ntype ExportAuditLogsOptions struct {\n\t// Format is the export format: \"csv\" or \"cef\". Empty defaults to \"csv\".\n\tFormat string\n\t// EventType filters the audit log to a single event type. Empty means no\n\t// filter.\n\tEventType string\n\t// User filters the audit log to events triggered by a single user, by\n\t// GitHub login. Empty means no filter.\n\tUser string\n\t// StartTime is the upper-bound timestamp of the time range to query, as\n\t// understood by the V1 endpoint. Empty means the service default.","sourceCodeStart":1723,"sourceCodeEnd":1759,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/pkg/backend/httpstate/client/client.go#L1723-L1759","documentation":"This error is returned by Client.ListAuditLogs when the GET /api/orgs/{orgName}/auditlogs REST call fails. It wraps the underlying restCall error so the caller can see both the operation and the cause (auth, permissions, bad query params, network). Empty ListAuditLogsOptions fields are simply omitted from the query string, so malformed dates/tokens are the main client-side causes.","triggerScenarios":"Calling ListAuditLogs(ctx, orgName, opts) when the GET request fails: invalid or expired token (401), insufficient permissions to view audit logs (403), unknown org (404), malformed start/end dates or continuation token, or network failure.","commonSituations":"Audit-export scripts run with a token from a service account lacking audit-log read permission; date ranges with wrong format; org renamed so the slug no longer matches.","solutions":["Verify PULUMI_ACCESS_TOKEN belongs to a user/role with audit log visibility (typically org Admin).","Check the org name matches the Pulumi Cloud slug and ListAuditLogsOptions dates/tokens are correctly formatted.","Clear the ContinuationToken and re-run from the first page if pagination broke.","Retry on transient errors; inspect the wrapped error for the HTTP status code."],"exampleFix":"// before\nresp, err := client.ListAuditLogs(ctx, orgName, opts)\nif err != nil { panic(err) }\n// after\nresp, err := client.ListAuditLogs(ctx, orgName, opts)\nif err != nil {\n    return fmt.Errorf(\"cannot read audit logs for %q: %w\", orgName, err)\n}","handlingStrategy":"validation","validationCode":"if orgName == \"\" {\n    return errors.New(\"organization name is required\")\n}\nif opts.StartTime != \"\" || opts.EndTime != \"\" {\n    // service expects RFC3339-style timestamps; validate format\n    for _, t := range []string{opts.StartTime, opts.EndTime} {\n        if t == \"\" { continue }\n        if _, err := time.Parse(time.RFC3339, t); err != nil {\n            return fmt.Errorf(\"invalid audit log timestamp %q: %w\", t, err)\n        }\n    }\n}","typeGuard":"func canReadAuditLogs(ctx context.Context, c *client.Client, org string) bool {\n    _, err := c.ListAuditLogs(ctx, org, apitype.ListAuditLogsOptions{})\n    var restErr *apitype.ErrorResponse\n    return err == nil || (errors.As(err, &restErr) && restErr.Code != 403)\n}","tryCatchPattern":"resp, err := client.ListAuditLogs(ctx, orgName, opts)\nvar restErr *apitype.ErrorResponse\nif errors.As(err, &restErr) {\n    switch restErr.Code {\n    case 401, 403:\n        return fmt.Errorf(\"audit log access denied for %q: %w\", orgName, err)\n    case 404:\n        return fmt.Errorf(\"organization %q not found\", orgName)\n    }\n}\nif err != nil {\n    return fmt.Errorf(\"listing audit logs: %w\", err) // transient: retry\n}","preventionTips":["Verify the token has audit-log visibility (usually org Admin).","Format StartTime/EndTime per the API's expected format before calling.","Use the org slug, not display name.","Reset ContinuationToken after any failure."],"tags":["http","pulumi-cloud","audit-logs","api-client"],"backgroundTag":"http-request-failed","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}