remix-run/remix · error · TypeError
${optionName} values must be package names. Received "${pack
Error message
${optionName} values must be package names. Received "${packageName}". What it means
Execution-time backstop: any command reaching the migration loader (`migrate`, `rollback`, `status`, `reset`) must have `plan.migrations` set. It duplicates the plan-time check so a hand-built or partially populated plan cannot proceed with an undefined migrations directory. CLI users normally hit the plan-time variant instead.
Source
Thrown at packages/assets/src/lib/access.ts:151
return inspect(filePath).allowed
},
}
}
function normalizePackageNames(
packageOption: readonly string[] | undefined,
optionName: 'allowPackages',
): Set<string> {
let packageNames = new Set<string>()
for (let packageName of packageOption ?? []) {
if (typeof packageName !== 'string') {
throw new TypeError(`${optionName} values must be strings`)
}
let normalizedPackageName = packageName.trim()
if (!isValidPackageName(normalizedPackageName)) {
throw new TypeError(`${optionName} values must be package names. Received "${packageName}".`)
}
packageNames.add(normalizedPackageName)
}
return packageNames
}
function validatePackageName(packageName: string, message: string): void {
if (!isValidPackageName(packageName)) {
throw new TypeError(message)
}
}
type PackageJson = {
dependencies?: Record<string, string>
optionalDependencies?: Record<string, string>
}View on GitHub (pinned to 9696913134)
Solutions
- Configure `db.migrations.directory` in remix.json or pass `--migrations`
- Always build plans through `resolveDatabaseCommandPlan`
- Validate the plan shape before executing
Example fix
// before
let plan = { command: 'migrate', db }
executeDatabaseCommand(plan)
// after
let plan = await resolveDatabaseCommandPlan(invocation, dbConfig)
executeDatabaseCommand(plan) Defensive patterns
Strategy: try-catch
Validate before calling
if (plan.command !== 'seed' && plan.command !== 'wipe' && plan.migrations === undefined) {
throw new Error('Plan is missing a migrations directory');
} Type guard
function isMigrationPlan(plan: any): plan is { command: string; migrations: string } {
return typeof plan.migrations === 'string';
} Try / catch
Catch around executeDatabaseCommand; on 'requires db.migrations.directory' fix remix.json or retry with --migrations.
Prevention
- Always build plans through the planner
- Keep db.migrations.directory configured
When it happens
Trigger: Programmatically invoking `executeDatabaseCommand` with a plan for a migration command where `migrations === undefined`, skipping `resolveDatabaseCommandPlan`.
Common situations: Direct plan construction in scripts/tests; refactors that copy plans between commands and drop the migrations field.
Related errors
- expected promise to resolve, but it rejected with: ${stringi
- ${optionName} values must be strings
- throw new AssertionError(options)
- ${matcherName} requires a mock function with a .mock.calls p
- throw new AssertionError({ message, actual, expected, operat
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/96c2702ba869c4cc.
Report an issue: GitHub.