RocketChat/Rocket.Chat · warning · InvalidUrlError

invalid-url

invalid-url

Error message

Invalid url

What it means

Thrown by the useExternalLink hook as an InvalidUrlError (a RocketChatError with error id 'invalid-url') when the supplied url is falsy — undefined, null, or empty string. The guard prevents window.open from being called with a blank target, which would open about:blank. Because it is a typed RocketChatError, callers can distinguish it via the `error` field equal to 'invalid-url'.

Source

Thrown at apps/meteor/client/hooks/useExternalLink.ts:8

import { useCallback } from 'react';

import { InvalidUrlError } from '../lib/errors/InvalidUrlError';

export const useExternalLink = () => {
	return useCallback((url: string | undefined) => {
		if (!url) {
			throw new InvalidUrlError();
		}
		window.open(url, '_blank', 'noopener noreferrer');
	}, []);
};

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Guard the call site: only invoke the callback when the URL is a non-empty string.
  2. If the URL may be undefined while loading, render a disabled link or a placeholder until it resolves.
  3. Catch InvalidUrlError specifically (check e.error === 'invalid-url') and show a friendly toast instead of letting it bubble.
  4. Validate/normalize the URL at the data source (API/integration) so empty strings never reach the renderer.

Example fix

// before
const openExternal = useExternalLink();
openExternal(message.externalUrl);

// after
const openExternal = useExternalLink();
if (message.externalUrl) {
  openExternal(message.externalUrl);
}
Defensive patterns

Strategy: validation

Validate before calling

const openExternal = useExternalLink();
if (typeof url === 'string' && url.trim().length > 0) {
  openExternal(url);
}

Type guard

function isNonEmptyUrl(url: unknown): url is string {
  return typeof url === 'string' && url.trim().length > 0;
}

Try / catch

try {
  openExternal(url);
} catch (e) {
  if (e instanceof InvalidUrlError && e.error === 'invalid-url') {
    dispatchToast({ type: 'warning', message: t('No_url_available') });
  }
}

Prevention

When it happens

Trigger: Calling the returned callback with no argument, with undefined (e.g. a link property not yet loaded from the API), or with '' (a trimmed/empty string from a malformed record). The check is purely `if (!url)` so any falsy value triggers it before window.open.

Common situations: A message/custom-field link whose value is still loading; a deleted/unset external URL field rendered before the fetch resolves; an integration webhook payload with a missing URL; user-supplied content where the URL was stripped by the sanitizer.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12). Data as JSON: /api/errors/dc7625e3eb3efa3e. Report an issue: GitHub.