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
- Verify message.actionLinks exists and contains an entry with method_id === actionMethodId before calling run.
- Ensure the UI only renders action buttons for messages that actually carry the relevant action link.
- If the message was edited/updated, re-fetch it so actionLinks reflects the latest state.
- 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
- Only render action buttons for messages whose actionLinks contain the method_id.
- Re-fetch edited messages so actionLinks reflect the latest state.
- Catch 'error-invalid-actionlink' to disable stale buttons.
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
- Invalid token for livechat message
- Invalid editor assigned to the message for the update.
- Invalid message id
- Invalid username
- Unrecognized typing scope provided
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/ec0c5160305d9763.
Report an issue: GitHub.