{"record":{"id":"c1c0e3d9fe9c0ecc","repo":"crowdsecurity/crowdsec","slug":"error-creating-transaction-w-w","errorCode":null,"errorMessage":"error creating transaction: %w: %w","messagePattern":"error creating transaction: %w: %w","errorType":"exception","errorClass":"BulkError","httpStatus":null,"severity":"error","filePath":"pkg/database/alerts.go","lineNumber":258,"sourceCode":"\t\tSetLeakSpeed(*alertItem.Leakspeed).\n\t\tSetSimulated(*alertItem.Simulated).\n\t\tSetScenarioVersion(*alertItem.ScenarioVersion).\n\t\tSetScenarioHash(*alertItem.ScenarioHash).\n\t\tSetKind(alertItem.Kind).\n\t\tSetRemediation(true) // it's from CAPI, we always have decisions\n\n\talertRef, err := alertB.Save(ctx)\n\tif err != nil {\n\t\treturn 0, 0, 0, fmt.Errorf(\"error creating alert: %w: %w\", err, BulkError)\n\t}\n\n\tif len(alertItem.Decisions) == 0 {\n\t\treturn alertRef.ID, 0, 0, nil\n\t}\n\n\ttxClient, err := c.Ent.Tx(ctx)\n\tif err != nil {\n\t\treturn 0, 0, 0, fmt.Errorf(\"error creating transaction: %w: %w\", err, BulkError)\n\t}\n\n\tdecOrigin := CapiMachineID\n\n\tif *alertItem.Decisions[0].Origin == CapiMachineID || *alertItem.Decisions[0].Origin == CapiListsMachineID {\n\t\tdecOrigin = *alertItem.Decisions[0].Origin\n\t} else {\n\t\tlog.Warningf(\"unexpected origin %s\", *alertItem.Decisions[0].Origin)\n\t}\n\n\tdeleted := 0\n\tinserted := 0\n\n\tdecisionBuilders := make([]*ent.DecisionCreate, 0, len(alertItem.Decisions))\n\tvalueList := make([]string, 0, len(alertItem.Decisions))\n\n\tfor _, decisionItem := range alertItem.Decisions {\n\t\tif decisionItem.Duration == nil {","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/alerts.go#L240-L276","documentation":"c.Ent.Tx(ctx) failed to open a database transaction before inserting the community-blocklist decisions; the error is wrapped with the BulkError sentinel for caller-side classification. This is an infrastructure failure, not a data problem: ent could not ask the driver to BEGIN a transaction.","triggerScenarios":"UpdateCommunityBlocklist (via SaveAlerts) with an alert that has decisions, when the underlying DB driver cannot start a transaction — connection already closed, SQLite lock contention, pool exhausted, or context cancelled/expired.","commonSituations":"Database server restarted or network blip during a large CAPI blocklist pull; SQLite database locked by a concurrent cscli command; connection-pool maxed out by other long-running queries.","solutions":["Verify database connectivity and re-run the pull; this is typically transient","If SQLite, check for concurrent processes holding the DB (lsof on the .db file) or switch to a server DB","Check driver connection-pool limits and the context deadline passed to SaveAlerts","Inspect the wrapped driver error — 'driver: bad connection' means the pool needs recycling (restart the service)"],"exampleFix":"// before\nctx := context.Background()\n// after (give the transaction a bounded deadline instead of inheriting a cancelled one)\nctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\ndefer cancel()","handlingStrategy":"retry","validationCode":"// verify the DB is reachable before the bulk pull\nctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\ndefer cancel()\nif _, err := c.Ent.Alert.Query().Limit(1).First(ctx); err != nil {\n    return fmt.Errorf(\"database unreachable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if _, _, _, err := db.UpdateCommunityBlocklist(ctx, alert); err != nil {\n    if errors.Is(err, database.BulkError) {\n        // transient tx failure: back off and retry the pull\n        time.Sleep(time.Second)\n        return retryPull()\n    }\n    return err\n}","preventionTips":["Set sane context deadlines for blocklist pulls so cancelled contexts don't leak into Tx()","Use a server DB (PostgreSQL/MySQL) for concurrent access instead of SQLite","Watch connection-pool saturation during large CAPI pulls","Alert on DB connectivity so transaction failures are caught at the source"],"tags":["database","transaction","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"}