{"record":{"id":"f0aafa3bec3c7749","repo":"remix-run/remix","slug":"expected-promise-to-resolve-but-it-rejected-with","errorCode":null,"errorMessage":"expected promise to resolve, but it rejected with: ${stringify(result.error)}","messagePattern":"expected promise to resolve, but it rejected with: (.+?)","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"packages/assert/src/lib/expect.ts","lineNumber":468,"sourceCode":"  promise: Promise<unknown> | (() => unknown),\n  mode: 'resolves' | 'rejects',\n  negated: boolean,\n): AsyncMatchers {\n  async function settle(): Promise<{ resolved: boolean; value?: unknown; error?: unknown }> {\n    try {\n      let value = await (typeof promise === 'function' ? promise() : promise)\n      return { resolved: true, value }\n    } catch (error) {\n      return { resolved: false, error }\n    }\n  }\n\n  function buildMatcher(matcher: keyof Matchers) {\n    return async (...args: unknown[]) => {\n      let result = await settle()\n      if (mode === 'resolves') {\n        if (!result.resolved) {\n          throw new AssertionError({\n            message: `expected promise to resolve, but it rejected with: ${stringify(result.error)}`,\n            actual: result.error,\n            operator: `resolves.${matcher}`,\n          })\n        }\n        let m = createMatchers(result.value, negated) as any\n        m[matcher](...args)\n      } else {\n        if (result.resolved) {\n          throw new AssertionError({\n            message: `expected promise to reject, but it resolved with: ${stringify(result.value)}`,\n            actual: result.value,\n            operator: `rejects.${matcher}`,\n          })\n        }\n        // For rejects.toThrow we check the error against the expected matcher.\n        if (matcher === 'toThrow') {\n          let pass = checkErrorMatch(result.error, args[0])","sourceCodeStart":450,"sourceCodeEnd":486,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/assert/src/lib/expect.ts#L450-L486","documentation":"The `migrate`, `reset`, `rollback`, and `status` commands all need a migrations directory, supplied by `db.migrations.directory` in `remix.json` or the `--migrations` flag. `resolveDatabaseCommandPlan` throws during planning when neither is set.","triggerScenarios":"Running `remix db migrate|reset|rollback|status` when `migrations === undefined` — no `db.migrations.directory` in remix.json and no `--migrations` CLI flag.","commonSituations":"Config defines adapter/filename but no migrations section; running migrations before any have been generated; forgetting the flag when testing a config-less invocation.","solutions":["Add `\"migrations\": { \"directory\": \"./migrations\" }` under `db` in remix.json","Or pass it per-run: `remix db migrate --migrations ./db/migrations`","Remember config paths resolve against the config directory, flag paths against the cwd"],"exampleFix":"# before\nremix db migrate\n# after\nremix db migrate --migrations ./db/migrations","handlingStrategy":"validation","validationCode":"let config = JSON.parse(fs.readFileSync('remix.json','utf8'));\nlet migrations = config?.db?.migrations?.directory ?? './migrations';\nrun(['remix','db','migrate','--migrations',migrations])","typeGuard":"function hasMigrationsDir(config: any): boolean {\n  return Boolean(config?.db?.migrations?.directory);\n}","tryCatchPattern":null,"preventionTips":["Always set db.migrations.directory in remix.json","Pass --migrations explicitly in scripts","Config paths resolve against the config dir, flag paths against cwd"],"tags":["cli","database","migrations","config"],"backgroundTag":"required-option-missing","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}