{"record":{"id":"c3abb7e06dd5749c","repo":"remix-run/remix","slug":"files-transforms-must-be-an-object","errorCode":null,"errorMessage":"files.transforms must be an object","messagePattern":"files\\.transforms must be an object","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/assets/src/lib/files/config.ts","lineNumber":215,"sourceCode":"      throw new TypeError(\n        `files.extensions values must use \".ext\" format. Received \"${extension}\".`,\n      )\n    }\n\n    if (reservedFileExtensions.has(normalizedExtension)) {\n      throw new TypeError(\n        `files.extensions cannot include compiled asset extensions like \"${normalizedExtension}\".`,\n      )\n    }\n\n    if (seen.has(normalizedExtension)) continue\n    seen.add(normalizedExtension)\n    normalizedExtensions.push(normalizedExtension)\n  }\n\n  let transforms = files.transforms ?? {}\n  if (transforms === null || typeof transforms !== 'object' || Array.isArray(transforms)) {\n    throw new TypeError('files.transforms must be an object')\n  }\n\n  let normalizedTransforms = new Map<\n    string,\n    AssetRequestTransform<string, AssetRequestTransformParamMode>\n  >()\n\n  for (let [name, transform] of Object.entries(transforms)) {\n    if (!/^[A-Za-z0-9_-]+$/.test(name)) {\n      throw new TypeError(\n        `files.transforms keys must use \"transform-name\" format. Received \"${name}\".`,\n      )\n    }\n\n    if (\n      transform === null ||\n      typeof transform !== 'object' ||\n      typeof transform.transform !== 'function'","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/assets/src/lib/files/config.ts#L197-L233","documentation":"When provided, `files.transforms` must be a plain object mapping transform names to transform definitions. This error fires when it is null, a non-object, or an array.","triggerScenarios":"Passing `files: { transforms: null }`, an array of transform objects, or a function where the object map is expected.","commonSituations":"Confusing `transforms` (named map) with `globalTransforms` (array); spreading optional config that leaves `null`; JSON configs with `\"transforms\": []`.","solutions":["Use a named map: `transforms: { md: { transform: fn } }`","Move array-style anonymous transforms to `files.globalTransforms`","Omit `transforms` if you have none"],"exampleFix":"// before\nfiles: { transforms: [{ transform: fn }] }\n// after\nfiles: { globalTransforms: [fn] }","handlingStrategy":"type-guard","validationCode":"if (files.transforms !== undefined && (typeof files.transforms !== 'object' || files.transforms === null || Array.isArray(files.transforms))) {\n  throw new Error('files.transforms must be an object map')\n}","typeGuard":"function isTransformMap(v: unknown): v is Record<string, { transform: Function }> {\n  return !!v && typeof v === 'object' && !Array.isArray(v)\n}","tryCatchPattern":null,"preventionTips":["Remember: transforms = named object map, globalTransforms = array","Omit optional config keys rather than setting null"],"tags":["config","files","transforms","validation"],"backgroundTag":"config-type-validation","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}