RocketChat/Rocket.Chat · warning · Error
Banner not found
Error message
Banner not found
What it means
Thrown by the banner service's dismiss() when the bannerId does not exist in the Banners collection AND the user has no banners.<bannerId>.read record. The method first tries the banner document; if absent it treats the id as an already-read legacy per-user banner and updates Users.setBannerReadById — when that matches nothing either, there is no banner to dismiss and it throws.
Solutions
- Treat 'Banner not found' as success (idempotent dismiss) in the caller
- Confirm the bannerId comes from a current Banners.findOneById query or the banner payload the client received
- Avoid re-dismissing after the first success
Example fix
// before
await bannerService.dismiss(userId, bannerId);
// after
try {
await bannerService.dismiss(userId, bannerId);
} catch (e) {
if (e.message !== 'Banner not found') throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
const banner = await Banners.findOneById(bannerId);
const userReadIt = Boolean(await Users.findOneByIdAndBannerRead(userId, bannerId));
if (!banner && !userReadIt) { /* treat as already dismissed, skip the call */ } Try / catch
try { await bannerService.dismiss(userId, bannerId); } catch (e) { if (e.message === 'Banner not found') { return true; /* idempotent success */ } throw e; } Prevention
- Track dismissed banner ids client-side to avoid repeat dismiss calls
- Treat dismissal as idempotent because banners can vanish at any time
When it happens
Trigger: dismiss(userId, 'stale-id') after the banner was deleted from the database; client retries dismissal with an id never issued; typos in bannerId.
Common situations: Race between a user closing a banner and an admin removing it; multiple tabs retrying dismiss after the first succeeded but the user record was reset; imports that drop banner documents but keep client-side state.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Banner not found
- error-application-not-found
- error-contact-not-found
- error-invalid-integration
- error-invalid-integration
AI-assisted analysis of RocketChat/Rocket.Chat@b2c16d5842 (2026-08-18).
Data as JSON: /api/errors/8f48a2754e3955ce.
Report an issue: GitHub.
Appendix: source
Thrown at apps/meteor/server/services/banner/service.ts:95
// such as the seatsTaken banner. In this case, we use the bannerId as the viewId
viewId: banner.view.viewId || banner._id,
},
// add surface to legacy banners
surface: !banner.surface ? 'banner' : banner.surface,
}));
}
async dismiss(userId: string, bannerId: string): Promise<boolean> {
if (!userId || !bannerId) {
throw new Error('Invalid params');
}
const banner = await Banners.findOneById(bannerId);
if (!banner) {
const { matchedCount } = await Users.setBannerReadById(userId, bannerId);
if (!matchedCount) {
throw new Error('Banner not found');
}
void notifyOnUserChange({
id: userId,
clientAction: 'updated',
diff: {
[`banners.${bannerId}.read`]: true,
},
});
return true;
}
const user = await Users.findOneById<Pick<IUser, 'username' | '_id'>>(userId, {
projection: { username: 1 },
});
if (!user) {
throw new Error('User not found');View on GitHub (pinned to b2c16d5842)