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
- Read the wrapped underlying error after 'failed: ' to identify the real DB failure
- Verify DB connectivity, credentials and network before running migrations
- Grant the migration user SELECT/CREATE privileges on the schema
- 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
- Use %w instead of %s when wrapping so errors.Is/As work
- Pre-flight DB connectivity and privileges before running migrations
- Run migrations as a dedicated user with DDL rights
- Log the task name together with the underlying error
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
- sync version failed: %v
- get config failed: %w
- update config failed: %w
- add config failed: %w
- get questions failed: %w
AI-assisted analysis of apache/answer@3b9f137061 (2026-09-05).
Data as JSON: /api/errors/959b7c9cc478740c.
Report an issue: GitHub.