{"record":{"id":"21f86a1226fe8148","repo":"ory/hydra","slug":"no-runner-defined-for-s","errorCode":null,"errorMessage":"no runner defined for %s","messagePattern":"no runner defined for (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"oryx/popx/migration_info.go","lineNumber":40,"sourceCode":"\tName string\n\t// Direction of the migration (up|down)\n\tDirection string\n\t// Type of migration (sql|go)\n\tType string\n\t// DB type (all|postgres|mysql...)\n\tDBType string\n\t// Runner function to run/execute the migration. Will be wrapped in a\n\t// database transaction. Mutually exclusive with RunnerNoTx\n\tRunner func(Migration, *pop.Connection) error\n\t// Content is the raw content of the migration file\n\tContent string\n\t// Autocommit indicates whether the migration should be run in autocommit mode\n\tAutocommit bool\n}\n\nfunc (m Migration) Valid() error {\n\tif m.Runner == nil {\n\t\treturn errors.Errorf(\"no runner defined for %s\", m.Path)\n\t}\n\n\treturn nil\n}\n\n// Migrations is a collection of Migration\ntype Migrations []Migration\n\nfunc (mfs Migrations) Len() int           { return len(mfs) }\nfunc (mfs Migrations) Less(i, j int) bool { return compareMigration(mfs[i], mfs[j]) < 0 }\nfunc (mfs Migrations) Swap(i, j int)      { mfs[i], mfs[j] = mfs[j], mfs[i] }\n\nfunc compareMigration(a, b Migration) int {\n\tif a.Version != b.Version {\n\t\treturn strings.Compare(a.Version, b.Version)\n\t}\n\t// Force \"all\" to be greater.\n\tif a.DBType == \"all\" && b.DBType != \"all\" {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/oryx/popx/migration_info.go#L22-L58","documentation":"Migration.Valid() asserts that every Migration carries a non-nil Runner function. A Migration struct built with Runner == nil fails validation with 'no runner defined for %s', where %s is the migration file path. This is a programmer/config error, not a runtime database issue.","triggerScenarios":"Constructing a Migration value programmatically (or via a custom loader) that omits the Runner field, then calling Valid() — which check() invokes for every up migration during NewMigrationBox.","commonSituations":"Custom migration loaders populating Version/Path but forgetting Runner; copying Migration construction code from older library versions where Runner didn't exist; SQL migrations registered without the standard file runner.","solutions":["Set the Runner field when building the Migration, e.g. the standard SQL file executor from the library","Use the library's migration factory/loader helpers instead of hand-assembling Migration structs","Check the library version's Migration struct fields and update custom construction code"],"exampleFix":"// before\nm := popx.Migration{Version: \"20240101120000\", Path: mf.Path}\n// after\nm := popx.Migration{Version: \"20240101120000\", Path: mf.Path, Runner: popx.NewSQLRunner(mf)}","handlingStrategy":"validation","validationCode":"// Validate custom-built migrations before handing them to NewMigrationBox\nfor i := range migrations {\n  if migrations[i].Runner == nil {\n    return fmt.Errorf(\"migration %s has nil Runner\", migrations[i].Path)\n  }\n  if err := migrations[i].Valid(); err != nil { return err }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the library's standard file loader instead of hand-building Migration structs","Set Runner at every construction site; keep a constructor helper that requires it","Re-check Migration struct fields after upgrading the library version","Add a unit test that runs Valid() over all registered migrations"],"tags":["migrations","go","configuration"],"backgroundTag":"missing-migration-runner","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}