{"record":{"id":"744438844f3530eb","repo":"crowdsecurity/crowdsec","slug":"insert-lock-w-w","errorCode":null,"errorMessage":"insert lock: %w: %w","messagePattern":"insert lock: %w: %w","errorType":"exception","errorClass":"InsertFail","httpStatus":null,"severity":"error","filePath":"pkg/database/lock.go","lineNumber":31,"sourceCode":"\nconst (\n\tCAPIPullLockTimeout = 10\n\tCapiPullLockName    = \"pullCAPI\"\n)\n\nfunc (c *Client) AcquireLock(ctx context.Context, name string) error {\n\tlog.Debugf(\"acquiring lock %s\", name)\n\t_, err := c.Ent.Lock.Create().\n\t\tSetName(name).\n\t\tSetCreatedAt(time.Now().UTC()).\n\t\tSave(ctx)\n\n\tif ent.IsConstraintError(err) {\n\t\treturn err\n\t}\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"insert lock: %w: %w\", err, InsertFail)\n\t}\n\n\treturn nil\n}\n\nfunc (c *Client) ReleaseLock(ctx context.Context, name string) error {\n\tlog.Debugf(\"releasing lock %s\", name)\n\t_, err := c.Ent.Lock.Delete().Where(lock.NameEQ(name)).Exec(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"delete lock: %w: %w\", err, DeleteFail)\n\t}\n\n\treturn nil\n}\n\nfunc (c *Client) ReleaseLockWithTimeout(ctx context.Context, name string, timeout int) error {\n\tlog.Debugf(\"releasing lock %s with timeout of %d minutes\", name, timeout)\n","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/lock.go#L13-L49","documentation":"AcquireLock wraps the error from inserting a row into the locks table, additionally tagging it with InsertFail. Constraint errors are returned unwrapped; everything else means the lock could not be persisted.","triggerScenarios":"`c.Ent.Lock.Create().SetName(name).Save(ctx)` fails with something other than a constraint error — DB unavailable, ctx canceled, or the locks table missing/corrupt.","commonSituations":"CAPI pull startup when MySQL/Postgres is unreachable; database schema out of date (missing locks table after partial migration); ctx deadline during LAPI startup.","solutions":["Check DB connectivity before LAPI/CAPI operations","Run `cscli hubtool` / `crowdsec -t` and ensure migrations ran (`cscli db migrate` equivalent — schema up to date)","Check `errors.Is(err, database.InsertFail)` in the caller to distinguish insert failure from other causes","Retry lock acquisition; it is safe to re-attempt"],"exampleFix":"// before\nerr := c.AcquireLock(ctx, name)\n// after\nif err := c.AcquireLock(ctx, name); err != nil {\n    if database.IsLocked(err) { return nil } // held elsewhere\n    if errors.Is(err, database.InsertFail) { log.Warn(\"db insert failed, retry later\") }\n    return err\n}","handlingStrategy":"retry","validationCode":"// verify schema has the locks table\nok, _ := c.Ent.Lock.Query().Limit(1).Exist(ctx)","typeGuard":null,"tryCatchPattern":"if err := c.AcquireLock(ctx, name); err != nil {\n    if database.IsLocked(err) { /* lock held elsewhere */ }\n    if errors.Is(err, database.InsertFail) { /* db insert failure, retry later */ }\n}","preventionTips":["Run migrations before starting LAPI","Keep DB credentials/connection stable across startup","Check errors.Is(err, database.InsertFail) to distinguish insert issues from lock contention"],"tags":["database","locking","ent"],"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"}