remix-run/remix · error · TypeError
${optionPath} must be an array
Error message
${optionPath} must be an array What it means
Options like `files.transformExtensions` (and sibling extension lists) must be arrays of strings when provided. normalizeTransformExtensions rejects any non-array value with a TypeError naming the exact option path.
Source
Thrown at packages/assets/src/lib/files/config.ts:322
}
return {
cache: files.cache,
extensions: normalizedExtensions,
globalTransforms: normalizedGlobalTransforms,
hasTransforms: normalizedTransforms.size > 0 || normalizedGlobalTransforms.length > 0,
maxRequestTransforms,
transforms: normalizedTransforms,
}
}
function normalizeTransformExtensions(
extensions: readonly string[] | undefined,
optionPath: string,
): readonly string[] | undefined {
if (extensions === undefined) return undefined
if (!Array.isArray(extensions)) {
throw new TypeError(`${optionPath} must be an array`)
}
if (extensions.length === 0) {
throw new TypeError(`${optionPath} must include at least one extension`)
}
let normalizedExtensions: string[] = []
let seen = new Set<string>()
for (let extension of extensions) {
if (typeof extension !== 'string') {
throw new TypeError(`${optionPath} values must be strings`)
}
let normalizedExtension = extension.trim().toLowerCase()
if (!/^\.[A-Za-z0-9_-]+$/.test(normalizedExtension)) {
throw new TypeError(`${optionPath} values must use ".ext" format. Received "${extension}".`)
}
View on GitHub (pinned to 9696913134)
Solutions
- Wrap the value in an array: ['.css']
- When parsing from env/CLI, split on commas and filter empties
- Leave the option undefined to accept the default extension set
Example fix
// before
files: { transformExtensions: '.css' }
// after
files: { transformExtensions: ['.css'] } Defensive patterns
Strategy: validation
Validate before calling
if (ext !== undefined && !Array.isArray(ext)) throw new Error('transformExtensions must be an array') Type guard
function isStringArray(v: unknown): v is readonly string[] {
return Array.isArray(v) && v.every((e) => typeof e === 'string')
} Prevention
- Split env-var strings on ',' before passing
- Type config fields as readonly string[] so TS flags strings
When it happens
Trigger: Passing `files: { transformExtensions: '.css' }` (a string instead of an array), a Set, or a comma-joined string like '.css,.js' to resolveAssetServerOptions.
Common situations: Reading extensions from an env var or CLI arg, which yields a string; spreading a possibly-undefined value; or assuming a single extension can be passed as a bare string.
Understand the failure class
Background: Invalid option value errors: "must be one of", "is not a valid", and "only allows" failures explained — this error's family across 23 libraries.
Related errors
- files.maxRequestTransforms must be a positive integer
- ${optionPath} must include at least one extension
- ${optionPath} values must be strings
- ${optionPath} values must use ".ext" format. Received "${ext
- ${optionPath} must be an object
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/c8baa218c0afac0b.
Report an issue: GitHub.