apache/answer · error

get first version failed: %v

Error message

get first version failed: %v

What it means

After syncing, GetCurrentDBVersion fetches the row with ID=1 from the version table. If that SELECT fails, the error is wrapped as 'get first version failed: %v', meaning the version table exists but could not be read.

Source

Thrown at internal/migrations/migrations.go:128

	NewMigration("v2.0.1", "change avatar type to text", updateAvatarType, false),
	NewMigration("v2.0.2", "add reasoning content to ai conversation record", addAIConversationReasoningContent, false),
	NewMigration("v2.0.3", "add require email verification login setting", addRequireEmailVerification, true),
}

func GetMigrations() []Migration {
	return migrations
}

// GetCurrentDBVersion returns the current db version
func GetCurrentDBVersion(engine *xorm.Engine) (int64, error) {
	if err := engine.Sync(new(entity.Version)); err != nil {
		return -1, fmt.Errorf("sync version failed: %v", err)
	}

	currentVersion := &entity.Version{ID: 1}
	has, err := engine.Get(currentVersion)
	if err != nil {
		return -1, fmt.Errorf("get first version failed: %v", err)
	}
	if !has {
		_, err := engine.InsertOne(&entity.Version{ID: 1, VersionNumber: 0})
		if err != nil {
			return -1, fmt.Errorf("insert first version failed: %v", err)
		}
		return 0, nil
	}
	return currentVersion.VersionNumber, nil
}

// ExpectedVersion returns the expected db version
func ExpectedVersion() int64 {
	return int64(minDBVersion + len(migrations))
}

// Migrate database to current version
func Migrate(debug bool, dbConf *data.Database, cacheConf *data.CacheConf, upgradeToSpecificVersion string) error {

View on GitHub (pinned to 3b9f137061)

Solutions

  1. Inspect the wrapped DB error for the root cause
  2. Verify SELECT privileges on the `version` table
  3. Point migrations at the primary DB, not a read replica
  4. Drop and recreate the empty version table if its schema is corrupt (only when safe)

Example fix

// before
return -1, fmt.Errorf("get first version failed: %v", err)
// after
return -1, fmt.Errorf("get first version failed: %w", err)
Defensive patterns

Strategy: retry

Validate before calling

// verify the version table is readable before migrating
if has, err := engine.IsTableExist(&entity.Version{}); err == nil && has {
    if _, err := engine.SQL("SELECT COUNT(*) FROM version").Query(); err != nil {
        return fmt.Errorf("version table unreadable: %w", err)
    }
}

Try / catch

version, err := migrations.GetCurrentDBVersion(engine)
if err != nil && strings.Contains(err.Error(), "get first version failed") {
    // transient DB issue: retry once after backoff
    time.Sleep(2 * time.Second)
    version, err = migrations.GetCurrentDBVersion(engine)
}

Prevention

When it happens

Trigger: engine.Get(currentVersion) on &entity.Version{ID:1} fails: table corrupted, connection dropped between Sync and Get, permissions deny SELECT on the version table, or driver/dialect error.

Common situations: Version table created by a different xorm version with incompatible column types; DB connection pool exhausted mid-migration; read-replica lag or read-only endpoint used for migrations.

Related errors


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