remix-run/remix · error · TypeError
files.extensions must be an array
Error message
files.extensions must be an array
What it means
When a `files` config object is provided to the asset server, its `extensions` field must be an array of file-extension strings. This error fires when `files.extensions` exists but is not an array (string, object, number, etc.).
Source
Thrown at packages/assets/src/lib/files/config.ts:184
const reservedFileExtensions = new Set<string>([...supportedScriptExtensions, '.css', '.map'])
const defaultMaxRequestTransforms = 5
export function normalizeFilesOptions<transforms extends AssetRequestTransformMap>(
files: AssetServerFilesOptions<transforms> | undefined,
): ResolvedAssetServerFilesOptions {
if (files == null) {
return {
extensions: [],
globalTransforms: [],
hasTransforms: false,
maxRequestTransforms: defaultMaxRequestTransforms,
transforms: new Map(),
}
}
if (!Array.isArray(files.extensions)) {
throw new TypeError('files.extensions must be an array')
}
let normalizedExtensions: string[] = []
let seen = new Set<string>()
for (let extension of files.extensions) {
if (typeof extension !== 'string') {
throw new TypeError('files.extensions values must be strings')
}
let normalizedExtension = extension.trim().toLowerCase()
if (!/^\.[A-Za-z0-9_-]+$/.test(normalizedExtension)) {
throw new TypeError(
`files.extensions values must use ".ext" format. Received "${extension}".`,
)
}
if (reservedFileExtensions.has(normalizedExtension)) {View on GitHub (pinned to 9696913134)
Solutions
- Wrap the value in an array: `extensions: ['.css', '.md']`
- If you don't want to override the defaults, omit `files.extensions` entirely
- Split comma-separated strings before passing: `extensions: raw.split(',')`
Example fix
// before
files: { extensions: '.css' }
// after
files: { extensions: ['.css'] } Defensive patterns
Strategy: type-guard
Validate before calling
if (filesConfig.extensions !== undefined && !Array.isArray(filesConfig.extensions)) {
throw new Error('files.extensions must be an array of strings')
} Type guard
function isExtensionArray(v: unknown): v is string[] {
return Array.isArray(v) && v.every((e) => typeof e === 'string')
} Prevention
- Always wrap single extensions in arrays
- Validate the whole files config once at app startup with a small schema check
When it happens
Trigger: Passing `files: { extensions: '.css' }` (a single string) or a non-array value like an object map of extensions.
Common situations: Copy-pasting a glob string or comma-separated list ('.css,.md') into `extensions`; config schemas from other tools (esbuild `loader` maps) pasted wholesale; YAML parsing a single item into a scalar instead of a list.
Related errors
- files.extensions values must be strings
- files.extensions values must use ".ext" format. Received "${
- files.extensions cannot include compiled asset extensions li
- files.transforms must be an object
- files.transforms.${name} must define a transform() function
AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27).
Data as JSON: /api/errors/d414ad595fa074f4.
Report an issue: GitHub.