{"record":{"id":"dcfd98d9516f34d1","repo":"crowdsecurity/crowdsec","slug":"bouncer-s-already-exists","errorCode":null,"errorMessage":"bouncer %s already exists","messagePattern":"bouncer (.+?) already exists","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/database/bouncers.go","lineNumber":93,"sourceCode":"\t\treturn nil, fmt.Errorf(\"listing bouncers: %w: %w\", err, QueryFail)\n\t}\n\n\treturn result, nil\n}\n\nfunc (c *Client) CreateBouncer(ctx context.Context, name string, ipAddr string, apiKey string, authType string, autoCreated bool) (*ent.Bouncer, error) {\n\tbouncer, err := c.Ent.Bouncer.\n\t\tCreate().\n\t\tSetName(name).\n\t\tSetAPIKey(apiKey).\n\t\tSetRevoked(false).\n\t\tSetAuthType(authType).\n\t\tSetIPAddress(ipAddr).\n\t\tSetAutoCreated(autoCreated).\n\t\tSave(ctx)\n\tif err != nil {\n\t\tif ent.IsConstraintError(err) {\n\t\t\treturn nil, fmt.Errorf(\"bouncer %s already exists\", name)\n\t\t}\n\n\t\treturn nil, fmt.Errorf(\"unable to create bouncer: %w\", err)\n\t}\n\n\treturn bouncer, nil\n}\n\nfunc (c *Client) DeleteBouncer(ctx context.Context, name string) error {\n\tnbDeleted, err := c.Ent.Bouncer.\n\t\tDelete().\n\t\tWhere(bouncer.NameEQ(name)).\n\t\tExec(ctx)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif nbDeleted == 0 {","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/bouncers.go#L75-L111","documentation":"CreateBouncer inserts a new bouncer row; when ent reports a constraint error (unique name or API key), the error is replaced with this friendly 'bouncer %s already exists' message instead of leaking the raw constraint error. It is a deliberate mapping, not a generic DB failure.","triggerScenarios":"Calling CreateBouncer (from 'cscli bouncers add', or TLS/plain bouncer auth with auto-registration) with a name or generated API key that already exists in the bouncers table.","commonSituations":"Re-running 'cscli bouncers add mybouncer' for an existing name; two bouncers auto-registering with the same configured name at startup.","solutions":["Use a unique name: 'cscli bouncers add <new-name>'","Delete the stale bouncer first: 'cscli bouncers delete <name>', then re-add","If it was auto-created, check whether the bouncer should reuse its existing API key instead of re-registering"],"exampleFix":"// before\ncscli bouncers add mybouncer\n// after - check existence first\ncscli bouncers list -o json | grep -q mybouncer || cscli bouncers add mybouncer","handlingStrategy":"validation","validationCode":"existing, _ := c.ListBouncers(ctx)\nfor _, b := range existing {\n    if b.Name == name {\n        return fmt.Errorf(\"bouncer %q already exists; delete it or pick another name\", name)\n    }\n}","typeGuard":null,"tryCatchPattern":"b, err := c.CreateBouncer(ctx, name, ip, key, authType, false)\nif err != nil {\n    if strings.Contains(err.Error(), \"already exists\") {\n        return fmt.Errorf(\"choose a different name or run: cscli bouncers delete %s\", name)\n    }\n    return err\n}","preventionTips":["Check 'cscli bouncers list' before adding a named bouncer","Use unique bouncer names per instance when auto-registering","Reuse an existing bouncer's key instead of re-creating it"],"tags":["database","bouncer","duplicate","constraint"],"backgroundTag":"resource-already-exists","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"}