RocketChat/Rocket.Chat · error · Meteor.Error
history-data-must-be-defined
history-data-must-be-defined
Error message
The history data must be defined to replay an integration.
What it means
Thrown by TriggerHandler.replay() when the supplied history entry has no `data` field. Replay reconstructs the original trigger payload (event, message, room, owner) from history.data; without it there is nothing to re-send, so the server refuses with Meteor.Error code 'history-data-must-be-defined'.
Source
Thrown at apps/meteor/server/lib/integrations/lib/triggerHandler.ts:804
})
.catch(async (err) => {
outgoingLogger.error({ err });
await updateHistory({
historyId,
step: 'after-http-call',
httpError: err,
httpResult: null,
});
});
}
async replay(integration: IOutgoingIntegration, history: IIntegrationHistory) {
if (integration?.type !== 'webhook-outgoing') {
throw new Meteor.Error('integration-type-must-be-outgoing', 'The integration type to replay must be an outgoing webhook.');
}
if (!history?.data) {
throw new Meteor.Error('history-data-must-be-defined', 'The history data must be defined to replay an integration.');
}
const { event } = history;
let owner;
let message;
let room;
let user;
if (history.data.owner?._id) {
owner = await Users.findOneById(history.data.owner._id);
}
if (history.data.message_id) {
message = await Messages.findOneById(history.data.message_id);
}
if (history.data.channel_id) {
room = await Rooms.findOneById(history.data.channel_id);
}
if (history.data.user_id) {View on GitHub (pinned to b2c16d5842)
Solutions
- Select a history entry from a real execution that contains data (check GET /api/v1/integrations.history for the integration)
- Prefer the latest 'after-http-call' entry so owner/message/room resolve cleanly
- Do not construct history objects yourself; always replay by historyId returned by the history API
Example fix
// before
await replay(integration, history);
// after
if (!history?.data) {
throw new Error('Pick a history entry that actually stored trigger data');
}
await replay(integration, history); Defensive patterns
Strategy: validation
Validate before calling
if (!history?.data) {
throw new Error('cannot replay: history entry has no stored trigger data');
}
await replay(integration, history); Type guard
const hasReplayableData = (h?: IIntegrationHistory): h is IIntegrationHistory & { data: NonNullable<IIntegrationHistory['data']> } =>
Boolean(h?.data); Try / catch
try {
await replay(integration, history);
} catch (err: any) {
if (err?.error === 'history-data-must-be-defined') {
// pick another historyId from integrations.history that has data
}
throw err;
} Prevention
- Only expose replay for history entries whose data field is present
- Prefer the most recent completed execution when choosing a historyId automatically
When it happens
Trigger: Calling integrations.replay with a historyId whose history record was written with no data (early-abort steps like 'after-prepare-no-url_or_method' still store data, but hand-crafted or pruned records may not); passing a history object built manually instead of one loaded from the integration history collection; history entries from a very old Rocket.Chat version with a different schema.
Common situations: Scripts that pick the first history entry rather than a completed delivery; deployments where history documents were partially purged; replaying entries whose original run failed before payload mapping.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- integration-type-must-be-outgoing
- error-invalid-event-type
- error-invalid-username
- error-invalid-targetRoom
- error-invalid-urls
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/79d4a354431c9ca9.
Report an issue: GitHub.