facebook/docusaurus · error · Error

Extension "${ext}" contains invalid URI characters. If the r

Error message

Extension "${ext}" contains invalid URI characters.
If the redirect extension system is not good enough for your use case, you can create redirects yourself with the "createRedirects" plugin option.

What it means

Thrown by validateExtension() when encodeURIComponent(ext) !== ext, i.e. the extension contains characters that are not URI-safe (spaces, unicode, #, ?, etc.). Redirect extensions become part of URLs, so they must already be in encoded form. This is the catch-all for invalid extensions that pass the empty/dot/slash checks but are still not URL-safe.

Source

Thrown at packages/docusaurus-plugin-client-redirects/src/extensionRedirects.ts:35

const validateExtension = (ext: string) => {
  if (!ext) {
    throw new Error(
      `Extension "${ext}" is not allowed.\n${ExtensionAdditionalMessage}`,
    );
  }
  if (ext.includes('.')) {
    throw new Error(
      `Extension "${ext}" contains a "." (dot) which is not allowed.\n${ExtensionAdditionalMessage}`,
    );
  }
  if (ext.includes('/')) {
    throw new Error(
      `Extension "${ext}" contains a "/" (slash) which is not allowed.\n${ExtensionAdditionalMessage}`,
    );
  }
  if (encodeURIComponent(ext) !== ext) {
    throw new Error(
      `Extension "${ext}" contains invalid URI characters.\n${ExtensionAdditionalMessage}`,
    );
  }
};

const addLeadingDot = (extension: string) => `.${extension}`;

/**
 * Create new `/path` that redirects to existing an `/path.html`
 */
export function createToExtensionsRedirects(
  paths: string[],
  extensions: string[],
): RedirectItem[] {
  extensions.forEach(validateExtension);

  const dottedExtensions = extensions.map(addLeadingDot);

View on GitHub (pinned to 3f483e80e3)

Solutions

  1. Use only ASCII alphanumeric extension tokens: 'html', 'htm', 'php', 'aspx'.
  2. Pre-encode any unusual token with encodeURIComponent before pushing it, or better, pick a plain ASCII name.
  3. Sanitize generated arrays: ext = encodeURIComponent(ext) and verify it equals the input.

Example fix

// before
fromExtensions: ['ht ml'],
// after
fromExtensions: ['html'],
Defensive patterns

Strategy: validation

Validate before calling

function assertUriSafe(ext: string): void {
  if (encodeURIComponent(ext) !== ext) {
    throw new Error(`Extension "${ext}" contains invalid URI characters.`);
  }
}

Type guard

const isUriSafeExtension = (e: unknown): e is string =>
  typeof e === 'string' && !!e && !e.includes('.') && !e.includes('/')
  && encodeURIComponent(e) === e;

Prevention

When it happens

Trigger: Configuring fromExtensions: ['htm lg'] (space), toExtensions: ['htéml'] (accented unicode), or any extension containing #, ?, %, spaces, or other reserved/unsafe URI characters. Reached in the forEach(validateExtension) loop after the empty/dot/slash guards.

Common situations: Pasting extensions from a spreadsheet that introduced non-breaking spaces; using localized/unicode tokens; a typo slipping a reserved character into the array.

Related errors


AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12). Data as JSON: /api/errors/f957147ee236a0b1. Report an issue: GitHub.