remix-run/remix · error · TypeError
throw new TypeError(message)
Error message
throw new TypeError(message)
What it means
`resolveDbString` resolves `RemixDbString` config values of the `{ env, default }` form: it uses `process.env[value.env]` and falls back to `value.default`. An env var that is set but empty is deliberately treated as unset; if the fallback also yields undefined or `''`, there's no usable connection value and it throws. Used for db filenames and connections created from config.
Source
Thrown at packages/assets/src/lib/access.ts:162
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>
}
type PackageRootPathTrie = {
children: Map<string, PackageRootPathTrie>
packageName?: string
}
type PackageRootQueueItem = {
packageJsonPath: string
packageName: string
}
View on GitHub (pinned to 9696913134)
Solutions
- Export the variable with a real value: `export DATABASE_FILE=./data.db`
- Add a `"default"` fallback in remix.json for local/dev runs
- Audit CI secret configuration — the secret may exist but inject an empty value
Example fix
// before
{ "db": { "filename": { "env": "DATABASE_FILE" } } }
// after
{ "db": { "filename": { "env": "DATABASE_FILE", "default": "./data.db" } } } Defensive patterns
Strategy: validation
Validate before calling
function resolveDbString(v: { env: string; default?: string }): string {
let out = process.env[v.env] || v.default;
if (out === undefined || out === '') throw new Error(`${v.env} is not set`);
return out;
}
let db = JSON.parse(fs.readFileSync('remix.json','utf8')).db;
resolveDbString(db.filename); // pre-check before running the CLI Type guard
function hasResolvableConnection(v: any): boolean {
if (typeof v === 'string') return v !== '';
return Boolean(process.env[v?.env] || v?.default);
} Prevention
- Always include a default for env-based connections
- Verify secrets exist in CI before db commands
- Empty env values fall back — don't rely on empty-set vars
When it happens
Trigger: Configuring `db.filename` (or another `RemixDbString`) as `{ env: 'DATABASE_FILE' }` with no `default` while `DATABASE_FILE` is unset or empty — `process.env[value.env] || value.default` resolves to undefined/`''`.
Common situations: CI missing the database secret; `.env` not loaded; configs written assuming the env var always exists; pipelines injecting empty-string values.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- throw new AssertionError({ message, actual, expected, operat
- expect(received).toThrow() requires a function (got ${typeof
- expected promise to resolve, but it rejected with: ${stringi
- expected promise to reject, but it resolved with: ${stringif
- expected error to be ${describeExpectedError(args[0])}, got
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/104be8a78fcf59c4.
Report an issue: GitHub.