{"record":{"id":"6190c51a26b04776","repo":"crowdsecurity/crowdsec","slug":"unable-to-create-alert-no-ids-returned-for-alert","errorCode":null,"errorMessage":"unable to create alert: no IDs returned for alert %s","messagePattern":"unable to create alert: no IDs returned for alert (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/database/alerts.go","lineNumber":64,"sourceCode":"\tif alertItem.UUID == \"\" {\n\t\treturn \"\", errors.New(\"alert UUID is empty\")\n\t}\n\n\talerts, err := c.Ent.Alert.Query().Where(alert.UUID(alertItem.UUID)).WithDecisions().All(ctx)\n\tif err != nil && !ent.IsNotFound(err) {\n\t\treturn \"\", fmt.Errorf(\"unable to query alerts for uuid %s: %w\", alertItem.UUID, err)\n\t}\n\n\t// alert wasn't found, insert it (expected hotpath)\n\tif ent.IsNotFound(err) || len(alerts) == 0 {\n\t\talertIDs, err := c.CreateAlert(ctx, machineID, []*models.Alert{alertItem})\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"unable to create alert: %w\", err)\n\t\t}\n\n\t\t// happy nilaway\n\t\tif len(alertIDs) == 0 {\n\t\t\treturn \"\", fmt.Errorf(\"unable to create alert: no IDs returned for alert %s\", alertItem.UUID)\n\t\t}\n\n\t\treturn alertIDs[0], nil\n\t}\n\n\t// this should never happen\n\tif len(alerts) > 1 {\n\t\treturn \"\", fmt.Errorf(\"multiple alerts found for uuid %s\", alertItem.UUID)\n\t}\n\n\tlog.Infof(\"Alert %s already exists, checking associated decisions\", alertItem.UUID)\n\n\t// alert is found, check for any missing decisions\n\n\tnewUuids := make([]string, len(alertItem.Decisions))\n\tfor i, decItem := range alertItem.Decisions {\n\t\tnewUuids[i] = decItem.UUID\n\t}","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/alerts.go#L46-L82","documentation":"A defensive invariant check: after CreateAlert reports success, the code expects at least one alert ID back. If the returned ID slice is empty (marked 'happy nilaway'), it returns 'unable to create alert: no IDs returned for alert %s'. This indicates an internal inconsistency — CreateAlert succeeded but returned no identifier — rather than a user-facing input problem.","triggerScenarios":"CreateAlert returns a non-nil, empty []string ID slice for a freshly inserted alert. Should be unreachable in normal operation; would occur only from an internal regression in CreateAlert's bulk-insert ID collection logic.","commonSituations":"Essentially only seen after a crowdsec bug or a modified/custom build; if encountered, it points to a defect in the alert insertion code path rather than to user configuration.","solutions":["Retry the alert push; the UUID lookup makes it idempotent","Check the crowdsec version for known CreateAlert bugs and upgrade","Capture logs and report upstream (github.com/crowdsec/crowdsec/issues) with the crowdsec version and DB backend","Verify with 'cscli alerts list' whether the alert was actually persisted despite the empty ID list"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"id, err := client.CreateOrUpdateAlert(ctx, machineID, alert)\nif err != nil && strings.Contains(err.Error(), \"no IDs returned\") {\n    // verify actual persistence instead of trusting the ID\n    alerts, qErr := client.QueryAlertWithUUID(ctx, alert.UUID)\n    if qErr == nil && len(alerts) == 1 { id = alerts[0].UUID }\n}","preventionTips":["Keep crowdsec up to date; this is an internal invariant, not a user error","Verify persistence via alert queries if the returned ID is empty","Report reproducible occurrences upstream with version and DB backend details"],"tags":["invariant","crowdsec","internal-error"],"backgroundTag":"internal-invariant-violation","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}