{"record":{"id":"bba109efd8ba7041","repo":"zitadel/zitadel","slug":"quota-8yxpk","errorCode":"QUOTA-8YXPk","errorMessage":"sorting slices of *quota.SetEventNotification with nil pointers is not supported","messagePattern":"sorting slices of \\*quota\\.SetEventNotification with nil pointers is not supported","errorType":"error_code","errorClass":"Internal","httpStatus":500,"severity":"error","filePath":"internal/command/quota_model.go","lineNumber":171,"sourceCode":"\tfor idx, notification := range q {\n\t\tnotifications[idx] = &quota.SetEventNotification{\n\t\t\tPercent: notification.Percent,\n\t\t\tRepeat:  notification.Repeat,\n\t\t\tCallURL: notification.CallURL,\n\t\t}\n\t\tnotifications[idx].ID, err = idGenerator.Next()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn notifications, nil\n}\n\n// sortSetEventNotifications reports an error if there are duplicate notifications or if a pointer is nil\nfunc sortSetEventNotifications(notifications []*quota.SetEventNotification) (err error) {\n\tslices.SortFunc(notifications, func(i, j *quota.SetEventNotification) int {\n\t\tif i == nil || j == nil {\n\t\t\terr = zerrors.ThrowInternal(errors.New(\"sorting slices of *quota.SetEventNotification with nil pointers is not supported\"), \"QUOTA-8YXPk\", \"Errors.Internal\")\n\t\t\treturn 0\n\t\t}\n\t\tif i.Percent == j.Percent && i.CallURL == j.CallURL && i.Repeat == j.Repeat {\n\t\t\t// TODO: translate\n\t\t\terr = zerrors.ThrowInternal(fmt.Errorf(\"%+v\", i), \"QUOTA-Pty2n\", \"Errors.Quota.Notifications.Duplicate\")\n\t\t\treturn 0\n\t\t}\n\t\tif i.Percent < j.Percent ||\n\t\t\ti.Percent == j.Percent && i.CallURL < j.CallURL ||\n\t\t\ti.Percent == j.Percent && i.CallURL == j.CallURL && !i.Repeat && j.Repeat {\n\t\t\treturn -1\n\t\t}\n\t\treturn +1\n\t})\n\treturn err\n}\n","sourceCodeStart":153,"sourceCodeEnd":188,"githubUrl":"https://github.com/zitadel/zitadel/blob/13948f2bcd6f257794dbd6d342c2ac30bc88fe54/internal/command/quota_model.go#L153-L188","documentation":"This internal error is thrown by sortSetEventNotifications in internal/command/quota_model.go when a *quota.SetEventNotification element in the slice being sorted is nil. The comparator cannot safely dereference nil pointers to compare Percent/CallURL/Repeat, so it aborts the sort with a zerrors internal error (code QUOTA-8YXPk). It is a programming/invariant error, not an expected runtime condition.","triggerScenarios":"Calling AddQuota/SetQuota (quota instance or org setup) with a Notifications slice that contains at least one nil *quota.SetEventNotification element; the nil element is hit when slices.SortFunc invokes the comparator.","commonSituations":"Building quota config programmatically where a notification entry failed to initialize or an optional notification was left nil instead of omitted from the slice; JSON/YAML config decoding that produced nil slice entries.","solutions":["Filter nil entries from the Notifications slice before passing quota to the command: notifications := slices.DeleteFunc(notifs, func(n *quota.SetEventNotification) bool { return n == nil })","Ensure every notification in the quota config is fully initialized (non-nil) when constructing quota.SetQuota","If a nil means 'no notification', omit the entry rather than including a nil pointer","If the error surfaces from deserialized config, fix the decoder/marshaling so empty entries become nil-free slices"],"exampleFix":"// before\nquota.Notifications = []*quota.SetEventNotification{emailNotif, nil, logNotif}\n// after\nquota.Notifications = []*quota.SetEventNotification{emailNotif, logNotif}","handlingStrategy":"validation","validationCode":"if slices.ContainsFunc(notifications, func(n *quota.SetEventNotification) bool { return n == nil }) {\n    return errors.New(\"quota notifications must not contain nil entries\")\n}","typeGuard":"func validNotifications(ns []*quota.SetEventNotification) bool {\n    return !slices.ContainsFunc(ns, func(n *quota.SetEventNotification) bool { return n == nil })\n}","tryCatchPattern":null,"preventionTips":["Never append nil pointers to config slices; skip empty entries at construction time","Sanitize slices with slices.DeleteFunc right after decoding config","Add a unit test asserting quota notifications contain no nil elements"],"tags":["go","quota","nil-pointer","internal-error"],"backgroundTag":"internal-invariant-violation","analyzedSha":"13948f2bcd6f257794dbd6d342c2ac30bc88fe54","analyzedAt":"2026-09-06T10:16:19.814Z","contentChangedAt":"2026-09-06T10:16:19.814Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}