apache/answer · error

get config failed: %w

Error message

get config failed: %w

What it means

This error is returned by the updateRolePinAndHideFeatures migration in internal/migrations/v11.go when the xorm Get() lookup of an existing config row (checking whether config ID like 125/126 exists) fails at the database level. The migration wraps the raw driver error with %w so the underlying cause (connection failure, locked table, bad schema) is preserved. It is thrown before any insert/update is attempted for that config row.

Source

Thrown at internal/migrations/v11.go:45

	"github.com/segmentfault/pacman/log"
	"xorm.io/xorm"
)

func updateRolePinAndHideFeatures(ctx context.Context, x *xorm.Engine) error {
	defaultConfigTable := []*entity.Config{
		{ID: 119, Key: "question.pin", Value: `0`},
		{ID: 120, Key: "question.unpin", Value: `0`},
		{ID: 121, Key: "question.show", Value: `0`},
		{ID: 122, Key: "question.hide", Value: `0`},
		{ID: 123, Key: "rank.question.pin", Value: `-1`},
		{ID: 124, Key: "rank.question.unpin", Value: `-1`},
		{ID: 125, Key: "rank.question.show", Value: `-1`},
		{ID: 126, Key: "rank.question.hide", Value: `-1`},
	}
	for _, c := range defaultConfigTable {
		exist, err := x.Context(ctx).Get(&entity.Config{ID: c.ID})
		if err != nil {
			return fmt.Errorf("get config failed: %w", err)
		}
		if exist {
			if _, err = x.Context(ctx).Update(c, &entity.Config{ID: c.ID}); err != nil {
				log.Errorf("update %+v config failed: %s", c, err)
				return fmt.Errorf("update config failed: %w", err)
			}
			continue
		}
		if _, err = x.Context(ctx).Insert(&entity.Config{ID: c.ID, Key: c.Key, Value: c.Value}); err != nil {
			log.Errorf("insert %+v config failed: %s", c, err)
			return fmt.Errorf("add config failed: %w", err)
		}
	}

	return nil
}

View on GitHub (pinned to 3b9f137061)

Solutions

  1. Check DB connectivity and credentials, then re-run the migration (migrations are typically idempotent)
  2. Inspect the wrapped cause (%w) in the error chain to see the driver-specific message
  3. Verify the config table exists and has the expected schema (id, key, value columns)
  4. Check server logs around the migration for lock timeouts or connection resets

Example fix

// before
exist, err := x.Context(ctx).Get(&entity.Config{ID: c.ID})
if err != nil {
	return fmt.Errorf("get config failed: %w", err)
}
// after (add retry for transient connection issues)
exist, err := x.Context(ctx).Get(&entity.Config{ID: c.ID})
if err != nil {
	if isTransientDBError(err) {
		time.Sleep(time.Second)
		exist, err = x.Context(ctx).Get(&entity.Config{ID: c.ID})
	}
	if err != nil {
		return fmt.Errorf("get config failed: %w", err)
	}
}
Defensive patterns

Strategy: retry

Validate before calling

// before running the migration
if err := db.Ping(); err != nil {
	return fmt.Errorf("database not reachable: %w", err)
}
if _, err := db.Exec("SELECT 1 FROM config LIMIT 1"); err != nil {
	return fmt.Errorf("config table unreadable: %w", err)
}

Try / catch

if err := runMigrations(); err != nil {
	var wrapped interface{ Unwrap() error }
	if errors.As(err, &target) { log.Fatalf("migration failed, cause: %v", target) }
}

Prevention

When it happens

Trigger: x.Context(ctx).Get(&entity.Config{ID: c.ID}) returns a non-nil err while iterating defaultConfigTable during the v11 migration run.

Common situations: Database unreachable or credentials wrong during upgrade; config table missing or corrupted; DB connection dropped mid-migration; read-only replica; table lock held by a concurrent migration.

Related errors


AI-assisted analysis of apache/answer@3b9f137061 (2026-09-05). Data as JSON: /api/errors/b88fccb8800a6bf6. Report an issue: GitHub.