{"record":{"id":"035372254796d1e0","repo":"crowdsecurity/crowdsec","slug":"unable-to-expire-decisions-v-w","errorCode":null,"errorMessage":"unable to expire decisions %+v: %w","messagePattern":"unable to expire decisions %\\+v: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apiserver/papi_cmd.go","lineNumber":63,"sourceCode":"\n\t\tUUIDs := make([]string, 0)\n\t\tdeleteDecisionMsg := deleteDecisions{\n\t\t\tDecisions: make([]string, 0),\n\t\t}\n\n\t\tif err := json.Unmarshal(data, &deleteDecisionMsg); err != nil {\n\t\t\treturn fmt.Errorf(\"message for '%s' contains bad data format: %w\", message.Header.OperationType, err)\n\t\t}\n\n\t\tUUIDs = append(UUIDs, deleteDecisionMsg.Decisions...)\n\t\tlog.Infof(\"Decisions UUIDs to remove: %+v\", UUIDs)\n\n\t\tfilter := make(map[string][]string)\n\t\tfilter[\"uuid\"] = UUIDs\n\n\t\t_, deletedDecisions, err := p.DBClient.ExpireDecisionsWithFilter(ctx, filter)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to expire decisions %+v: %w\", UUIDs, err)\n\t\t}\n\n\t\tdecisions := make([]*models.Decision, 0)\n\n\t\tfor _, deletedDecision := range deletedDecisions {\n\t\t\tlog.Infof(\"Decision from '%s' for '%s' (%s) has been deleted\", deletedDecision.Origin, deletedDecision.Value, deletedDecision.Type)\n\t\t\tdec := &models.Decision{\n\t\t\t\tUUID:     deletedDecision.UUID,\n\t\t\t\tOrigin:   &deletedDecision.Origin,\n\t\t\t\tScenario: &deletedDecision.Scenario,\n\t\t\t\tScope:    &deletedDecision.Scope,\n\t\t\t\tValue:    &deletedDecision.Value,\n\t\t\t\tID:       int64(deletedDecision.ID),\n\t\t\t\tUntil:    deletedDecision.Until.String(),\n\t\t\t\tType:     &deletedDecision.Type,\n\t\t\t}\n\t\t\tdecisions = append(decisions, dec)\n\t\t}","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/apiserver/papi_cmd.go#L45-L81","documentation":"After parsing UUIDs from a delete-decisions PAPI message, DecisionCmd expires the matching decisions in the local database via ExpireDecisionsWithFilter. This error means the database expiry operation failed, so remote deletion orders could not be applied locally.","triggerScenarios":"p.DBClient.ExpireDecisionsWithFilter returns an error — DB connectivity failure, SQL error, lock timeout, or an unsupported database backend.","commonSituations":"Database down or restarting (e.g. in a cluster), disk full, DB migration pending, SQLite lock contention under heavy load.","solutions":["Check database connectivity and logs for the underlying wrapped SQL error","Verify the database schema is up to date (cscli migrations / version match)","Retry the pull once the DB is healthy","Check disk space and DB lock contention"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if err := p.DBClient.Ping(ctx); err != nil { return fmt.Errorf(\"database unavailable before expiring decisions\") }","typeGuard":null,"tryCatchPattern":"if err := DecisionCmd(ctx, msg, p, false); err != nil { if strings.Contains(err.Error(), \"unable to expire decisions\") { /* retry with backoff; check DB health */ } }","preventionTips":["Monitor database connectivity and disk space","Apply schema migrations before starting the service","Avoid SQLite under high concurrency where possible"],"tags":["database","papi","decisions"],"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"}