remix-run/remix · error · TypeError

files.maxRequestTransforms must be a positive integer

Error message

files.maxRequestTransforms must be a positive integer

What it means

The assets package validates the `files.maxRequestTransforms` option before using it. It must be an integer greater than or equal to 1 because it caps how many request transforms can be chained per asset request. Any non-integer (float, string, NaN) or value below 1 throws immediately during option normalization.

Source

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

      throw new TypeError(`files.globalTransforms[${index}].name must be a string`)
    }

    if (typeof transform.transform !== 'function') {
      throw new TypeError(`files.globalTransforms[${index}] must define a transform() function`)
    }

    normalizedGlobalTransforms.push({
      ...transform,
      extensions: normalizeTransformExtensions(
        transform.extensions,
        `files.globalTransforms[${index}].extensions`,
      ),
    })
  }

  let maxRequestTransforms = files.maxRequestTransforms ?? defaultMaxRequestTransforms
  if (!Number.isInteger(maxRequestTransforms) || maxRequestTransforms < 1) {
    throw new TypeError('files.maxRequestTransforms must be a positive integer')
  }

  if (files.cache !== undefined) {
    if (
      files.cache === null ||
      typeof files.cache !== 'object' ||
      typeof files.cache.get !== 'function' ||
      typeof files.cache.set !== 'function'
    ) {
      throw new TypeError('files.cache must implement the FileStorage interface')
    }
  }

  return {
    cache: files.cache,
    extensions: normalizedExtensions,
    globalTransforms: normalizedGlobalTransforms,
    hasTransforms: normalizedTransforms.size > 0 || normalizedGlobalTransforms.length > 0,

View on GitHub (pinned to 9696913134)

Solutions

  1. Set a positive integer such as 16 (the default) or higher
  2. If deriving from env/config, wrap with Number() and validate with Number.isInteger before passing
  3. Remove the option entirely to use the default limit

Example fix

// before
resolveAssetServerOptions({ files: { maxRequestTransforms: 0 } })
// after
resolveAssetServerOptions({ files: { maxRequestTransforms: 16 } })
Defensive patterns

Strategy: validation

Validate before calling

const v = options.files?.maxRequestTransforms
if (v !== undefined && (!Number.isInteger(v) || v < 1)) throw new Error('fix maxRequestTransforms')

Type guard

function isValidMaxTransforms(v: unknown): v is number {
  return typeof v === 'number' && Number.isInteger(v) && v >= 1
}

Prevention

When it happens

Trigger: Passing `files: { maxRequestTransforms: 0 }`, a negative number, a float like 2.5, or a non-number (e.g. '10' as a string, NaN from bad arithmetic) to resolveAssetServerOptions/normalizeFilesOptions.

Common situations: Setting maxRequestTransforms to 0 thinking it disables the limit, computing the value from env vars or config math that yields NaN/fractions, or copying a value from another tool with different semantics.

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/0f4f17039c2b4417. Report an issue: GitHub.