{"record":{"id":"750e6b78bae5acf9","repo":"apache/answer","slug":"update-config-failed-w","errorCode":null,"errorMessage":"update config failed: %w","messagePattern":"update config failed: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/migrations/v11.go","lineNumber":50,"sourceCode":"\tdefaultConfigTable := []*entity.Config{\n\t\t{ID: 119, Key: \"question.pin\", Value: `0`},\n\t\t{ID: 120, Key: \"question.unpin\", Value: `0`},\n\t\t{ID: 121, Key: \"question.show\", Value: `0`},\n\t\t{ID: 122, Key: \"question.hide\", Value: `0`},\n\t\t{ID: 123, Key: \"rank.question.pin\", Value: `-1`},\n\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":32,"sourceCodeEnd":62,"githubUrl":"https://github.com/apache/answer/blob/3b9f1370612e690a0b7f230f05e688930db4c6d3/internal/migrations/v11.go#L32-L62","documentation":"Returned by updateRolePinAndHideFeatures when xorm Update() of an existing config row (rank.question.show / rank.question.hide) fails. The row was found via Get(), but persisting the new value errored. The underlying driver error is wrapped with %w.","triggerScenarios":"x.Context(ctx).Update(c, &entity.Config{ID: c.ID}) returns non-nil err for a config row that already exists (exist == true) in the v11 migration.","commonSituations":"Write permission denied for the DB user; constraint violation on the config table; connection lost between the Get and the Update; DB in read-only mode during maintenance.","solutions":["Read the wrapped driver error to identify the exact SQL failure","Verify the DB user has UPDATE privilege on the config table","Check for schema mismatches between entity.Config and the actual table","Re-run the migration after fixing the DB issue; it is safe to retry"],"exampleFix":"// before\nif _, err = x.Context(ctx).Update(c, &entity.Config{ID: c.ID}); err != nil {\n\tlog.Errorf(\"update %+v config failed: %s\", c, err)\n\treturn fmt.Errorf(\"update config failed: %w\", err)\n}\n// after (log the SQL/args for diagnosis)\nif _, err = x.Context(ctx).Update(c, &entity.Config{ID: c.ID}); err != nil {\n\tlog.Errorf(\"update config id=%d key=%s failed: %s\", c.ID, c.Key, err)\n\treturn fmt.Errorf(\"update config id=%d failed: %w\", c.ID, err)\n}","handlingStrategy":"try-catch","validationCode":"// verify write access beforehand\nif _, err := db.Exec(\"UPDATE config SET value = value WHERE id = -1\"); err != nil {\n\treturn fmt.Errorf(\"no UPDATE privilege on config: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := runMigrations(); err != nil {\n\tif strings.Contains(err.Error(), \"update config failed\") {\n\t\tlog.Fatalf(\"config write failed, cause: %v\", errors.Unwrap(err))\n\t}\n\treturn err\n}","preventionTips":["Ensure the migration DB user has UPDATE privileges","Stop app nodes before running migrations to avoid lock contention","Back up the config table before upgrading","Check DB error logs after any failed upgrade"],"tags":["database","migration","xorm","config-update"],"backgroundTag":"migration-db-write-failed","analyzedSha":"3b9f1370612e690a0b7f230f05e688930db4c6d3","analyzedAt":"2026-09-05T18:18:39.533Z","contentChangedAt":"2026-09-05T18:18:39.533Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}