apache/answer · error

%s failed: %s

Error message

%s failed: %s

What it means

Mentor.do wraps any error produced by a migration step fn with the task name, producing '<taskName> failed: <underlying error>'. It is the migration runner's way of attributing a failure to the specific step (e.g. checkTableExist) during InitDB.

Source

Thrown at internal/migrations/init.go:101

	m.do("init site info privilege rank", m.initSiteInfoPrivilegeRank)
	m.do("init site info write", m.initSiteInfoAdvanced)
	m.do("init site info write", m.initSiteInfoQuestions)
	m.do("init site info write", m.initSiteInfoTags)
	m.do("init site info security", m.initSiteInfoSecurityConfig)
	m.do("init default content", m.initDefaultContent)
	m.do("init default badges", m.initDefaultBadges)
	m.do("init default ai config", m.initSiteInfoAI)
	m.do("init default MCP config", m.initSiteInfoMCP)
	return m.err
}

func (m *Mentor) do(taskName string, fn func()) {
	if m.err != nil || m.Done {
		return
	}
	fn()
	if m.err != nil {
		m.err = fmt.Errorf("%s failed: %s", taskName, m.err)
	}
}

func (m *Mentor) checkTableExist() {
	m.Done, m.err = m.engine.Context(m.ctx).IsTableExist(&entity.Version{})
	if m.Done {
		fmt.Println("[database] already exists")
	}
}

func (m *Mentor) syncTable() {
	m.err = m.engine.Context(m.ctx).Sync(tables...)
}

func (m *Mentor) initVersionTable() {
	_, m.err = m.engine.Context(m.ctx).Insert(&entity.Version{ID: 1, VersionNumber: ExpectedVersion()})
}

View on GitHub (pinned to 3b9f137061)

Solutions

  1. Read the wrapped underlying error after 'failed: ' to identify the real DB failure
  2. Verify DB connectivity, credentials and network before running migrations
  3. Grant the migration user SELECT/CREATE privileges on the schema
  4. Re-run InitDB after fixing; Mentor skips already-done steps

Example fix

// before
m.err = fmt.Errorf("%s failed: %s", taskName, m.err)
// after
m.err = fmt.Errorf("%s failed: %w", taskName, m.err) // preserve wrap for errors.Is
Defensive patterns

Strategy: try-catch

Validate before calling

// before InitDB, verify connectivity
if err := db.Ping(); err != nil {
    return fmt.Errorf("database unreachable: %w", err)
}

Try / catch

if err := migrations.InitDB(engine); err != nil {
    if strings.Contains(err.Error(), "failed: ") {
        var dbErr error
        errors.As(err, &dbErr) // inspect wrapped cause when %w is used
        log.Errorf("migration task failed: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Any migration task executed by Mentor.do fails — e.g. engine.Context(ctx).IsTableExist(&entity.Version{}) returns a DB error (connection failure, permissions, dialect mismatch) — then m.err is wrapped as '<task> failed: ...'.

Common situations: Database unreachable or credentials wrong during bootstrap; migration user lacks privileges to query information_schema; xorm driver/dialect incompatibility with the DB version; context cancelled mid-migration.

Related errors


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