{"record":{"id":"59ca8fa625454d80","repo":"apache/answer","slug":"add-config-failed-w","errorCode":null,"errorMessage":"add config failed: %w","messagePattern":"add config failed: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/migrations/v11.go","lineNumber":56,"sourceCode":"\t\t{ID: 124, Key: \"rank.question.unpin\", Value: `-1`},\n\t\t{ID: 125, Key: \"rank.question.show\", Value: `-1`},\n\t\t{ID: 126, Key: \"rank.question.hide\", Value: `-1`},\n\t}\n\tfor _, c := range defaultConfigTable {\n\t\texist, err := x.Context(ctx).Get(&entity.Config{ID: c.ID})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"get config failed: %w\", err)\n\t\t}\n\t\tif exist {\n\t\t\tif _, err = x.Context(ctx).Update(c, &entity.Config{ID: c.ID}); err != nil {\n\t\t\t\tlog.Errorf(\"update %+v config failed: %s\", c, err)\n\t\t\t\treturn fmt.Errorf(\"update config failed: %w\", err)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif _, err = x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil {\n\t\t\tlog.Errorf(\"insert %+v config failed: %s\", c, err)\n\t\t\treturn fmt.Errorf(\"add config failed: %w\", err)\n\t\t}\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":38,"sourceCodeEnd":62,"githubUrl":"https://github.com/apache/answer/blob/3b9f1370612e690a0b7f230f05e688930db4c6d3/internal/migrations/v11.go#L38-L62","documentation":"Returned by updateRolePinAndHideFeatures when xorm Insert() of a missing config row (ID 125/126, rank.question.show/hide) fails. This path runs when the config row does not yet exist. The driver error is wrapped with %w.","triggerScenarios":"x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}) returns non-nil err when the config row was absent (exist == false) in the v11 migration.","commonSituations":"Another node inserted the same config ID concurrently causing a duplicate-key error; ID sequence out of sync; insufficient INSERT privileges; disk full on the DB host.","solutions":["Check the wrapped error for a duplicate-key violation; if so, the row was inserted concurrently and the migration can be re-run","Verify INSERT privilege for the DB user on the config table","Check free disk space and DB health","Re-run the migration; Get/Insert logic is idempotent"],"exampleFix":"// before\nif _, err = x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil {\n\treturn fmt.Errorf(\"add config failed: %w\", err)\n}\n// after (treat duplicate key as success)\nif _, err = x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil {\n\tif isDuplicateKeyError(err) {\n\t\tcontinue\n\t}\n\treturn fmt.Errorf(\"add config failed: %w\", err)\n}","handlingStrategy":"retry","validationCode":"// ensure the row does not already exist to avoid duplicate keys\nvar count int64\ndb.QueryRow(\"SELECT COUNT(*) FROM config WHERE id = 125\").Scan(&count)\n// if count > 0 the migration already ran; safe to skip","typeGuard":null,"tryCatchPattern":"if err := runMigrations(); err != nil {\n\tif strings.Contains(err.Error(), \"add config failed\") && isDuplicateKey(errors.Unwrap(err)) {\n\t\tlog.Println(\"config row already present; treating as success\")\n\t\treturn nil\n\t}\n\treturn err\n}","preventionTips":["Run migrations from a single instance (avoid multi-node concurrent upgrades)","Verify INSERT privileges on the config table","Check for duplicate-key errors in the wrapped cause before panicking","Keep enough free disk space on the DB host"],"tags":["database","migration","xorm","config-insert"],"backgroundTag":"db-duplicate-key-violation","analyzedSha":"3b9f1370612e690a0b7f230f05e688930db4c6d3","analyzedAt":"2026-09-05T18:18:39.533Z","contentChangedAt":"2026-09-05T18:18:39.533Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}