RocketChat/Rocket.Chat · error · MeteorError

error-invalid-preview

error-invalid-preview

Error message

Preview Item must have an id, type, and value.

What it means

executePreviewResponse() validates the selected SlashCommandPreviewItem before delegating to the command's previewCallback: it must be a complete { id, type, value } triple. This protects command implementations from acting on half-built items. The check is truthiness-based, so empty strings in any of the three fields also trigger it.

Source

Thrown at apps/meteor/server/lib/utils/slashCommand.ts:128

		command: string,
		params: string,
		message: Pick<IMessage, 'rid'> & Partial<Omit<IMessage, 'rid'>>,
		preview: SlashCommandPreviewItem,
		userId: string,
		triggerId?: string,
	) {
		const cmd = this.commands[command];
		if (typeof cmd?.previewCallback !== 'function') {
			return;
		}

		if (!message?.rid) {
			throw new MeteorError('invalid-command-usage', 'Executing a command requires at least a message with a room id.');
		}

		// { id, type, value }
		if (!preview.id || !preview.type || !preview.value) {
			throw new MeteorError('error-invalid-preview', 'Preview Item must have an id, type, and value.');
		}

		return cmd.previewCallback(command, params, message, preview, userId, triggerId);
	},
};

declare module '@rocket.chat/ddp-client' {
	// eslint-disable-next-line @typescript-eslint/naming-convention
	interface ServerMethods {
		slashCommand(params: { cmd: string; params: string; msg: IMessage; triggerId: string }): unknown;
	}
}

Meteor.methods<ServerMethods>({
	async slashCommand(command) {
		methodDeprecationLogger.method('slashCommand', '9.0.0', '/v1/commands.run');
		const userId = Meteor.userId();
		if (!userId) {

View on GitHub (pinned to b2c16d5842)

Solutions

  1. Pass the exact SlashCommandPreviewItem object received from getPreviews back into executePreviewResponse.
  2. If you must rebuild items, populate all three fields with non-empty values.
  3. Validate the item shape at the boundary when previews cross serialization layers.

Example fix

// before: rebuilt item lost 'value' -> error-invalid-preview
await slashCommands.executePreviewResponse('gimme', 'cat', msg, { id: item.id, type: item.type } as SlashCommandPreviewItem, userId);

// after: send the full item from getPreviews()
await slashCommands.executePreviewResponse('gimme', 'cat', msg, item, userId);
Defensive patterns

Strategy: validation

Validate before calling

// Mirror of the server-side truthiness check
const isValidPreviewItem = (p: SlashCommandPreviewItem): boolean =>
  Boolean(p && p.id && p.type && p.value);

Type guard

const isCompletePreviewItem = (p: unknown): p is SlashCommandPreviewItem => {
  const c = p as { id?: unknown; type?: unknown; value?: unknown } | null;
  return Boolean(c && c.id && c.type && c.value);
};

Try / catch

try {
  await slashCommands.executePreviewResponse(cmd, params, message, preview, userId);
} catch (err: any) {
  if (err?.error === 'error-invalid-preview') {
    // item shape lost in transit: refresh previews via getPreviews instead of retrying the stale item
    return refreshPreviews(cmd, params, message, userId);
  }
  throw err;
}

Prevention

When it happens

Trigger: executePreviewResponse invoked with a preview item like { id: '1', type: 'image' } (no value) or any field as '' ; client code synthesizing a slimmer item object instead of passing back exactly what getPreviews returned; serialization round-trips that drop falsy values.

Common situations: UI state mapping preview items to { id } only; JSON/DDP transport dropping fields; refactors of the command palette payload shape.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18). Data as JSON: /api/errors/6e14d176030031ad. Report an issue: GitHub.