{"record":{"id":"9175dfbe07ea986b","repo":"crowdsecurity/crowdsec","slug":"while-saving-alert-from-s-w","errorCode":null,"errorMessage":"while saving alert from %s: %w","messagePattern":"while saving alert from (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apiserver/apic.go","lineNumber":891,"sourceCode":"\t\tdecisions[outIdx] = decision\n\t\toutIdx++\n\t}\n\t// shrink the list, those are deleted items\n\treturn decisions[:outIdx]\n}\n\nfunc (a *apic) SaveAlerts(ctx context.Context, alertsFromCapi []*models.Alert, addCounters map[string]map[string]int, deleteCounters map[string]map[string]int) error {\n\tfor _, alert := range alertsFromCapi {\n\t\tsetAlertScenario(alert, addCounters, deleteCounters)\n\t\tlog.Debugf(\"%s has %d decisions\", *alert.Source.Scope, len(alert.Decisions))\n\n\t\tif a.dbClient.Type == \"sqlite\" && (a.dbClient.WalMode == nil || !*a.dbClient.WalMode) {\n\t\t\tlog.Warningf(\"sqlite is not using WAL mode, LAPI might become unresponsive when inserting the community blocklist\")\n\t\t}\n\n\t\talertID, inserted, deleted, err := a.dbClient.UpdateCommunityBlocklist(ctx, alert)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"while saving alert from %s: %w\", *alert.Source.Scope, err)\n\t\t}\n\n\t\tlog.Printf(\"%s : added %d entries, deleted %d entries (alert:%d)\", *alert.Source.Scope, inserted, deleted, alertID)\n\t}\n\n\treturn nil\n}\n\nfunc (a *apic) ShouldForcePullBlocklist(ctx context.Context, blocklist *modelscapi.BlocklistLink) (bool, error) {\n\t// we should force pull if the blocklist decisions are about to expire or there's no decision in the db\n\talertQuery := a.dbClient.Ent.Alert.Query()\n\talertQuery.Where(alert.SourceScopeEQ(fmt.Sprintf(\"%s:%s\", types.ListOrigin, *blocklist.Name)))\n\talertQuery.Order(ent.Desc(alert.FieldCreatedAt))\n\n\talertInstance, err := alertQuery.First(ctx)\n\tif err != nil {\n\t\tif ent.IsNotFound(err) {\n\t\t\tlog.Debugf(\"no alert found for %s, force refresh\", *blocklist.Name)","sourceCodeStart":873,"sourceCodeEnd":909,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/apiserver/apic.go#L873-L909","documentation":"SaveAlerts wraps the error returned by dbClient.UpdateCommunityBlocklist when persisting a CAPI community-blocklist alert and its decisions. The inner error comes from the database layer (constraint violations, DB unavailable, context cancelled).","triggerScenarios":"PullTop or updateBlocklist saves fetched blocklist alerts; UpdateCommunityBlocklist fails, e.g. SQLite locked/corrupted, PostgreSQL down, context deadline exceeded during long CAPI pulls, or a malformed decision from CAPI violating schema.","commonSituations":"SQLite without WAL mode under concurrent LAPI writes, DB restart during community blocklist pull, disk full, huge community blocklist insert timing out, DB migration not applied after upgrade.","solutions":["Inspect the wrapped inner error to identify the DB-layer cause.","Enable WAL mode for SQLite (`cscli db enable-wal`) and run `cscli db doctor`.","Verify DB connectivity and that migrations ran (`cscli db migrate` / restart crowdsec).","Increase pull timeout / check disk space if the error is a timeout or write failure."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// verify DB is reachable before large pulls:\n// cscli db doctor && cscli db enable-wal","typeGuard":null,"tryCatchPattern":"if err := a.SaveAlerts(ctx, alerts, addCounters, nil); err != nil {\n    var dbErr *ent.ConstraintError\n    if errors.As(err, &dbErr) { /* handle duplicate/conflict */ }\n    return fmt.Errorf(\"...: %w\", err)\n}","preventionTips":["Enable WAL mode for SQLite before enabling community blocklist pull.","Monitor disk space on the DB volume.","Apply DB migrations after every crowdsec upgrade."],"tags":["database","sqlite","postgresql","capi","blocklist"],"backgroundTag":"database-write-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"}