{"record":{"id":"959b7c9cc478740c","repo":"apache/answer","slug":"s-failed-s","errorCode":null,"errorMessage":"%s failed: %s","messagePattern":"(.+?) failed: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/migrations/init.go","lineNumber":101,"sourceCode":"\tm.do(\"init site info privilege rank\", m.initSiteInfoPrivilegeRank)\n\tm.do(\"init site info write\", m.initSiteInfoAdvanced)\n\tm.do(\"init site info write\", m.initSiteInfoQuestions)\n\tm.do(\"init site info write\", m.initSiteInfoTags)\n\tm.do(\"init site info security\", m.initSiteInfoSecurityConfig)\n\tm.do(\"init default content\", m.initDefaultContent)\n\tm.do(\"init default badges\", m.initDefaultBadges)\n\tm.do(\"init default ai config\", m.initSiteInfoAI)\n\tm.do(\"init default MCP config\", m.initSiteInfoMCP)\n\treturn m.err\n}\n\nfunc (m *Mentor) do(taskName string, fn func()) {\n\tif m.err != nil || m.Done {\n\t\treturn\n\t}\n\tfn()\n\tif m.err != nil {\n\t\tm.err = fmt.Errorf(\"%s failed: %s\", taskName, m.err)\n\t}\n}\n\nfunc (m *Mentor) checkTableExist() {\n\tm.Done, m.err = m.engine.Context(m.ctx).IsTableExist(&entity.Version{})\n\tif m.Done {\n\t\tfmt.Println(\"[database] already exists\")\n\t}\n}\n\nfunc (m *Mentor) syncTable() {\n\tm.err = m.engine.Context(m.ctx).Sync(tables...)\n}\n\nfunc (m *Mentor) initVersionTable() {\n\t_, m.err = m.engine.Context(m.ctx).Insert(&entity.Version{ID: 1, VersionNumber: ExpectedVersion()})\n}\n","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/apache/answer/blob/3b9f1370612e690a0b7f230f05e688930db4c6d3/internal/migrations/init.go#L83-L119","documentation":"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.","triggerScenarios":"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: ...'.","commonSituations":"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.","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"],"exampleFix":"// before\nm.err = fmt.Errorf(\"%s failed: %s\", taskName, m.err)\n// after\nm.err = fmt.Errorf(\"%s failed: %w\", taskName, m.err) // preserve wrap for errors.Is","handlingStrategy":"try-catch","validationCode":"// before InitDB, verify connectivity\nif err := db.Ping(); err != nil {\n    return fmt.Errorf(\"database unreachable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := migrations.InitDB(engine); err != nil {\n    if strings.Contains(err.Error(), \"failed: \") {\n        var dbErr error\n        errors.As(err, &dbErr) // inspect wrapped cause when %w is used\n        log.Errorf(\"migration task failed: %v\", err)\n    }\n    return err\n}","preventionTips":["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"],"tags":["database","migration","xorm"],"backgroundTag":"migration-step-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"}