RocketChat/Rocket.Chat · warning · Error

error-invalid-actionlink

error-invalid-actionlink

Error message

error-invalid-actionlink

What it means

Thrown by actionLinks.run when no actionLink on the message matches the requested actionMethodId. The function searches message.actionLinks for an entry whose method_id equals actionMethodId; if none is found it throws 'error-invalid-actionlink'. This mirrors the server-side error code so the client and server share vocabulary.

Source

Thrown at apps/meteor/client/lib/actionLinks.ts:27

	register(name: string, fn: (message: IMessage, params: string) => void): void {
		actionLinks.actions.set(name, fn);
	},
	run(actionMethodId: string, message: IMessage): void {
		const embedded = isLayoutEmbedded();

		if (embedded) {
			fireGlobalEvent('click-action-link', {
				actionlink: actionMethodId,
				value: message._id,
				message,
			});
			return;
		}

		const actionLink = message.actionLinks?.find((action) => action.method_id === actionMethodId);

		if (!actionLink) {
			throw new Error('error-invalid-actionlink');
		}

		if (!actionLinks.actions.has(actionLink.method_id)) {
			throw new Error('error-invalid-actionlink');
		}

		const fn = actionLinks.actions.get(actionLink.method_id);
		fn?.(message, actionLink.params);
	},
};

View on GitHub (pinned to f9d3ec372b)

Solutions

  1. Verify message.actionLinks exists and contains an entry with method_id === actionMethodId before calling run.
  2. Ensure the UI only renders action buttons for messages that actually carry the relevant action link.
  3. If the message was edited/updated, re-fetch it so actionLinks reflects the latest state.
  4. Catch 'error-invalid-actionlink' and hide/disable the button gracefully.

Example fix

// before
actionLinks.run(actionMethodId, message);

// after
const link = message.actionLinks?.find((a) => a.method_id === actionMethodId);
if (link) {
  actionLinks.run(actionMethodId, message);
}
Defensive patterns

Strategy: validation

Validate before calling

const link = message.actionLinks?.find((a) => a.method_id === actionMethodId);
if (!link) { throw new Error('Action link not attached to message'); }

Type guard

function messageHasActionLink(message: IMessage, methodId: string): boolean {
  return Array.isArray(message.actionLinks) &&
    message.actionLinks.some((a) => a.method_id === methodId);
}

Try / catch

try {
  actionLinks.run(actionMethodId, message);
} catch (e) {
  if ((e as Error).message === 'error-invalid-actionlink') {
    hideActionButton();
  }
}

Prevention

When it happens

Trigger: Calling actionLinks.run(actionMethodId, message) where the message has no actionLinks array, or none of its entries have method_id === actionMethodId. Common when a UI button references an action link that was never attached to the message (e.g. a stale message object, a button rendered for the wrong message type).

Common situations: The message is a plain text message with no action links but the UI still rendered an action button; the actionLink was removed by an edit; the method_id was renamed; a bot/integration attached an action link the client does not expect; clicking an action button after navigating away and the message ref is stale.

Related errors


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