remix-run/remix · error · TypeError

files.transforms.${name}.param must be true or "optional"

Error message

files.transforms.${name}.param must be true or "optional"

What it means

A transform's optional `param` field controls whether the transform accepts a URL parameter. It must be exactly `true` (required param) or the string `'optional'` (optional param); any other value is rejected. `undefined`/absent is fine and means no param.

Source

Thrown at packages/assets/src/lib/files/config.ts:244

        `files.transforms keys must use "transform-name" format. Received "${name}".`,
      )
    }

    if (
      transform === null ||
      typeof transform !== 'object' ||
      typeof transform.transform !== 'function'
    ) {
      throw new TypeError(`files.transforms.${name} must define a transform() function`)
    }

    if (
      'param' in transform &&
      transform.param !== undefined &&
      transform.param !== true &&
      transform.param !== 'optional'
    ) {
      throw new TypeError(`files.transforms.${name}.param must be true or "optional"`)
    }

    normalizedTransforms.set(name, {
      ...transform,
      extensions: normalizeTransformExtensions(
        transform.extensions,
        `files.transforms.${name}.extensions`,
      ),
    })
  }

  let globalTransforms = files.globalTransforms ?? []
  if (!Array.isArray(globalTransforms)) {
    throw new TypeError('files.globalTransforms must be an array')
  }

  let normalizedGlobalTransforms: ResolvedAssetGlobalTransform[] = []

View on GitHub (pinned to 9696913134)

Solutions

  1. Remove the `param` field to disable parameters
  2. Use `param: true` for a required parameter or `param: 'optional'` for an optional one

Example fix

// before
files: { transforms: { md: { transform: fn, param: 'required' } } }
// after
files: { transforms: { md: { transform: fn, param: true } } }
Defensive patterns

Strategy: validation

Validate before calling

for (let t of Object.values(files.transforms ?? {})) {
  if ('param' in t && t.param !== undefined && t.param !== true && t.param !== 'optional') {
    delete t.param // or throw
  }
}

Type guard

function isValidParam(p: unknown): boolean {
  return p === undefined || p === true || p === 'optional'
}

Prevention

When it happens

Trigger: Passing `param: false`, `param: 'required'`, `param: 'true'`, or a non-'optional' string on a transform definition.

Common situations: Assuming `param: false` is the way to disable params (just omit the field); using the string `'required'` which is not accepted; copy-paste from docs of a different version.

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


AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27). Data as JSON: /api/errors/4d2d8b9d4f673655. Report an issue: GitHub.