remix-run/remix · error · TypeError

Expected at most ${maxTransforms} request transforms

Error message

Expected at most ${maxTransforms} request transforms

What it means

serializeAssetTransformInvocations enforces the maximum number of request transforms (default 16) that can be applied to a single asset request. It throws when the invocation list exceeds the configured cap, protecting URL length and transform-chain performance.

Source

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

    if (!/^\.[A-Za-z0-9_-]+$/.test(normalizedExtension)) {
      throw new TypeError(`${optionPath} values must use ".ext" format. Received "${extension}".`)
    }

    if (seen.has(normalizedExtension)) continue
    seen.add(normalizedExtension)
    normalizedExtensions.push(normalizedExtension)
  }

  return normalizedExtensions
}

export function serializeAssetTransformInvocations<transforms extends AssetRequestTransformMap>(
  transforms: readonly AssetTransformInvocation<transforms>[],
  transformsByName: ResolvedAssetRequestTransformMap,
  maxTransforms = defaultMaxRequestTransforms,
): string[] {
  if (transforms.length > maxTransforms) {
    throw new TypeError(`Expected at most ${maxTransforms} request transforms`)
  }

  return transforms.map((transformInvocation) =>
    normalizeAssetTransformInvocation(transformInvocation, transformsByName, (message) => {
      throw new TypeError(message)
    }),
  )
}

export function parseAssetTransformInvocations(
  transformsQuery: readonly string[],
  transformsByName: ResolvedAssetRequestTransformMap,
  maxTransforms = defaultMaxRequestTransforms,
): readonly (string | readonly [string, string])[] {
  if (transformsQuery.length > maxTransforms) {
    throw new TypeError(`Expected at most ${maxTransforms} request transforms`)
  }

View on GitHub (pinned to 9696913134)

Solutions

  1. Raise the cap by passing a larger maxRequestTransforms consistently to both the server options and the serialization call
  2. Filter/reduce the transform chain to only necessary transforms
  3. If invoking serializeAssetTransformInvocations directly, pass an explicit maxTransforms argument

Example fix

// before
serializeAssetTransformInvocations(invocations, map) // 17 invocations, default cap 16
// after
serializeAssetTransformInvocations(invocations, map, 32)
Defensive patterns

Strategy: validation

Validate before calling

if (invocations.length > maxTransforms) {
  invocations = invocations.slice(0, maxTransforms) // or raise the cap
}

Try / catch

try { serializeAssetTransformInvocations(list, map) } catch (e) { if (e instanceof TypeError && /request transforms/.test(e.message)) { /* trim chain or raise cap */ } throw e }

Prevention

When it happens

Trigger: Calling getHrefTransform (or serializeAssetTransformInvocations directly) with more than `maxTransforms` transform invocations, e.g. 17 entries when the cap is 16.

Common situations: Building transform chains dynamically (one per query param or per layer) that grow past 16; raising `files.maxRequestTransforms` in one place but not where serialization runs; browser extensions or middleware appending extra transforms.

Related errors


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