{"record":{"id":"abf0e62573b72774","repo":"crowdsecurity/crowdsec","slug":"select-config-item-w-w","errorCode":null,"errorMessage":"select config item: %w: %w","messagePattern":"select config item: %w: %w","errorType":"exception","errorClass":"QueryFail","httpStatus":null,"severity":"error","filePath":"pkg/database/config.go","lineNumber":18,"sourceCode":"package database\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/crowdsecurity/crowdsec/pkg/database/ent\"\n\t\"github.com/crowdsecurity/crowdsec/pkg/database/ent/configitem\"\n)\n\nfunc (c *Client) GetConfigItem(ctx context.Context, key string) (string, error) {\n\tresult, err := c.Ent.ConfigItem.Query().Where(configitem.NameEQ(key)).First(ctx)\n\n\tswitch {\n\tcase ent.IsNotFound(err):\n\t\treturn \"\", nil\n\tcase err != nil:\n\t\treturn \"\", fmt.Errorf(\"select config item: %w: %w\", err, QueryFail)\n\tdefault:\n\t\treturn result.Value, nil\n\t}\n}\n\nfunc (c *Client) SetConfigItem(ctx context.Context, key string, value string) error {\n\terr := c.Ent.ConfigItem.\n\t\tCreate().\n\t\tSetName(key).\n\t\tSetValue(value).\n\t\tOnConflictColumns(configitem.FieldName).\n\t\tUpdateNewValues().\n\t\tExec(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"insert/update config item: %w\", err)\n\t}\n\n\treturn nil","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/config.go#L1-L36","documentation":"GetConfigItem wraps a failed query for a config_items row by name. Not-found is treated as an empty value (\"\", nil); any other query error is wrapped as `select config item: <err>: <QueryFail>`. Called by Pull, QueryPAPIInfo, updateBlocklist, LoadAPICToken.","triggerScenarios":"Database unreachable/corrupted, malformed schema (config_items table missing after a failed migration), or context cancellation while querying a known key like ca_path, blocklist, or api credentials.","commonSituations":"Partially migrated/corrupted SQLite file where the ent query itself errors; MySQL outage during crowdsec Pull; permissions making the DB unreadable.","solutions":["Inspect the double-wrapped error: the first %w is the driver cause, QueryFail is the sentinel","Verify DB connectivity and that the schema is up to date (cscli may need `crowdsec` restart to run migrations)","Check file permissions on the SQLite database","Retry transient network errors if using MySQL/Postgres"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// treat empty value as legitimate missing key — this API already does\nval, err := c.GetConfigItem(ctx, key)\nif err != nil && val == \"\" { /* err is a real query failure */ }","typeGuard":null,"tryCatchPattern":"val, err := c.GetConfigItem(ctx, \"ca_path\")\nswitch {\ncase err == nil && val == \"\": // key absent, use default\ncase err != nil: return fmt.Errorf(\"cannot read config item: %w\", err)\n}","preventionTips":["Distinguish not-found (empty, nil) from real query errors","Keep DB migrations current before reading config items","Check DB permissions on the SQLite file","Retry on remote-DB transient failures"],"tags":["database","ent","config","query"],"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-14T05:17:10.506Z"}