{"record":{"id":"2fa0ae023250a896","repo":"crowdsecurity/crowdsec","slug":"unable-to-query-alerts-for-uuid-s-w","errorCode":null,"errorMessage":"unable to query alerts for uuid %s: %w","messagePattern":"unable to query alerts for uuid (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/database/alerts.go","lineNumber":52,"sourceCode":"func rollbackOnError(tx *ent.Tx, err error, msg string) error {\n\tif rbErr := tx.Rollback(); rbErr != nil {\n\t\tlog.Errorf(\"rollback error: %v\", rbErr)\n\t}\n\n\treturn fmt.Errorf(\"%s: %w\", msg, err)\n}\n\n// CreateOrUpdateAlert is specific to PAPI : It checks if alert already exists, otherwise inserts it\n// if alert already exists, it checks it associated decisions already exists\n// if some associated decisions are missing (ie. previous insert ended up in error) it inserts them\nfunc (c *Client) CreateOrUpdateAlert(ctx context.Context, machineID string, alertItem *models.Alert) (string, error) {\n\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","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/alerts.go#L34-L70","documentation":"CreateOrUpdateAlert queries the alerts table for an alert by UUID; if the ent query itself fails with an error other than not-found, the alert cannot be checked and this wrapped error is returned. It means the lookup SELECT against the alert repository failed, not that the alert is missing (missing alerts are handled by inserting a new one).","triggerScenarios":"c.Ent.Alert.Query().Where(alert.UUID(...)).WithDecisions().All(ctx) returns a non-NotFound error: DB connection failure, SQLite lock/timeout, corrupted schema, or context cancellation during the PAPI AlertCmd flow.","commonSituations":"SQLite file locked by another crowdsec process; database migrated to a schema the binary doesn't understand after upgrade; DB unreachable (remote PostgreSQL/MySQL down); context deadline exceeded on a slow disk.","solutions":["Check DB connectivity and credentials in crowdsec's db_config","Run 'cscli db migrate' / confirm the DB schema matches the installed crowdsec version","For SQLite locks, look for other processes holding the DB and consider moving to PostgreSQL/MySQL","Retry the operation once connectivity/locks are resolved; the operation is idempotent by alert UUID"],"exampleFix":"// before: treating any error as fatal without checking DB\n// after: surface the cause and verify DB health first\nif _, err := client.CreateOrUpdateAlert(ctx, machineID, alert); err != nil {\n    if err := dbHealthCheck(ctx); err != nil {\n        return fmt.Errorf(\"db unhealthy: %w\", err)\n    }\n    return err\n}","handlingStrategy":"retry","validationCode":"// verify DB reachable before pushing alerts\nif err := c.Ent.Schema.Create(ctx) /* or a trivial query */; err != nil { return err }\nif alertItem.UUID == \"\" { return errors.New(\"pre-check: alert UUID is empty\") }","typeGuard":null,"tryCatchPattern":"id, err := client.CreateOrUpdateAlert(ctx, machineID, alert)\nif err != nil && strings.HasPrefix(err.Error(), \"unable to query alerts\") {\n    // DB-level failure, not 'not found': retry after health check\n    if isDbHealthy(ctx) { id, err = client.CreateOrUpdateAlert(ctx, machineID, alert) }\n}","preventionTips":["Health-check the DB connection before bulk PAPI pushes","Use context timeouts generous enough for SQLite under load","Match crowdsec binary and DB schema versions on upgrade","Serialize alert pushes rather than issuing them concurrently from many clients"],"tags":["database","query","crowdsec","ent"],"backgroundTag":"database-query-failed","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}