RocketChat/Rocket.Chat · error · Meteor.Error
invalid-params
invalid-params
Error message
tshow provided but missing tmid
What it means
executeSendMessage validates thread payload shape first: if message.tshow is set but message.tmid is missing it throws invalid-params ('tshow provided but missing tmid'). tshow means 'also show this thread reply in the main channel' and is meaningless without a parent thread id, so the pair is enforced up front.
Source
Thrown at apps/meteor/server/meteor-methods/messages/sendMessage.ts:38
import { metrics } from '../../lib/metrics';
import { settings } from '../../settings';
/**
*
* @param uid
* @param message
* @param extraInfo
* - ts: The timestamp of the message. the message object already has a ts, but this value is validated and only a window of 10 seconds is allowed to be used. this value overrides the message.ts value without validation.
*
*
* @returns
*/
export async function executeSendMessage(
uid: IUser['_id'] | IUser,
message: AtLeast<IMessage, 'rid'>,
extraInfo?: { ts?: Date; previewUrls?: string[] },
) {
if (message.tshow && !message.tmid) {
throw new Meteor.Error('invalid-params', 'tshow provided but missing tmid', {
method: 'sendMessage',
});
}
if (message.tmid && !settings.get('Threads_enabled')) {
throw new Meteor.Error('error-not-allowed', 'not-allowed', {
method: 'sendMessage',
});
}
const isTimestampFromClient = Boolean(!extraInfo?.ts && message.ts);
const now = new Date();
message.ts = extraInfo?.ts ?? message.ts ?? now;
if (isTimestampFromClient) {
const tsDiff = Math.abs(moment(message.ts).diff(Date.now()));
if (tsDiff > 60000) {
throw new Meteor.Error('error-message-ts-out-of-sync', 'Message timestamp is out of sync', {
method: 'sendMessage',View on GitHub (pinned to b2c16d5842)
Solutions
- Only set tshow on actual thread replies where tmid is present
- Assign tmid before tshow when building the payload so the invariant cannot be violated
- For normal channel messages omit tshow entirely
Example fix
// before
const message = { rid, msg, tshow: true };
await Meteor.callAsync('sendMessage', message);
// after
const message = { rid, msg, ...(tmid ? { tmid, tshow: true } : {}) };
await Meteor.callAsync('sendMessage', message); Defensive patterns
Strategy: validation
Validate before calling
// invariant: tshow requires tmid
const isValidThreadPayload = (m: { tmid?: string; tshow?: boolean }): boolean =>
!m.tshow || Boolean(m.tmid);
if (!isValidThreadPayload(message)) {
delete message.tshow;
}
await Meteor.callAsync('sendMessage', message); Type guard
const hasValidThreadShape = (
m: { tmid?: string; tshow?: boolean },
): m is { tmid: string; tshow?: boolean } =>
typeof m.tmid === 'string' && m.tmid.length > 0 && (!('tshow' in m) || !m.tshow || true) && Boolean(m.tshow) === Boolean(m.tshow && m.tmid); Try / catch
try {
await Meteor.callAsync('sendMessage', message);
} catch (e: any) {
if (e?.error === 'invalid-params' && e?.reason?.includes('tshow')) {
// payload bug: rebuild with tmid set or tshow removed, then resend
}
throw e;
} Prevention
- Build thread payloads by assigning tmid before tshow
- Add a unit test asserting tshow is never sent without tmid
- Strip thread-only fields when reusing payload templates for normal messages
When it happens
Trigger: Sending { rid, msg, tshow: true } with no tmid; client code that sets tshow first and conditionally assigns tmid later; reusing a thread-reply payload template for a normal channel message without clearing tshow.
Common situations: Copy-pasted message-building code where the tmid branch was removed but tshow stayed; UI toggle for 'show in channel' left on while the reply context was lost; refactor that renamed tmid but kept tshow.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- error-not-allowed
- error-message-ts-out-of-sync
- error-invalid-message
- error-invalid-update-key
- error-invalid-message
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/9d59a29751d6d998.
Report an issue: GitHub.