RocketChat/Rocket.Chat · error · Error
app-addon-not-valid
app-addon-not-valid
Error message
app-addon-not-valid
What it means
Thrown by _canEnableApp when app.info.addon is set and License.hasModule(<addon>) is false — the app declares a required addon module that the current license does not include. Plain Error. Migrated apps return early before this check, so it only affects apps installed after the addon validation was introduced.
Source
Thrown at apps/meteor/ee/server/lib/license/canEnableApp.ts:25
type _canEnableAppDependencies = {
Apps: typeof Apps;
License: LicenseImp;
};
export const _canEnableApp = async ({ Apps, License }: _canEnableAppDependencies, app: IAppStorageItem): Promise<void> => {
if (!(await Apps.isInitialized())) {
throw new Error('apps-engine-not-initialized');
}
// Migrated apps were installed before the validation was implemented
// so they're always allowed to be enabled
if (app.migrated) {
return;
}
if (app.info.addon && !License.hasModule(app.info.addon as LicenseModule)) {
throw new Error('app-addon-not-valid');
}
const source = getInstallationSourceFromAppStorageItem(app);
switch (source) {
case 'private':
if (await License.shouldPreventAction('privateApps')) {
throw new Error('license-prevented');
}
break;
default:
if (await License.shouldPreventAction('marketplaceApps')) {
throw new Error('license-prevented');
}
const marketplaceInfo = app.marketplaceInfo?.[0];
if (marketplaceInfo?.isEnterpriseOnly && !License.hasValidLicense()) {
throw new Error('invalid-license');View on GitHub (pinned to f9d3ec372b)
Solutions
- Acquire/apply a license that includes the required addon module and retry.
- Install a version of the app that does not require the addon, if available.
- If the app was migrated from a pre-validation install, mark app.migrated = true (only valid for genuine migrations).
Example fix
// before
await canEnableApp(app); // throws app-addon-not-valid
// after
if (app.info.addon && !License.hasModule(app.info.addon)) {
throw new Error(`Apply a license including module '${app.info.addon}' before enabling ${app.info.name}`);
} Defensive patterns
Strategy: validation
Validate before calling
async function canEnableAddonApp(app: IAppStorageItem): Promise<boolean> {
return !app.info.addon || License.hasModule(app.info.addon as LicenseModule);
} Type guard
const declaresAddon = (app: IAppStorageItem): boolean => Boolean(app?.info?.addon);
Try / catch
try { await canEnableApp(app); } catch (e) {
if (e instanceof Error && e.message === 'app-addon-not-valid') { /* apply license with module or use other app version */ } else throw e;
} Prevention
- Check License.hasModule(app.info.addon) in the marketplace UI before showing Enable.
- Document addon requirements on app listings.
When it happens
Trigger: Enabling an app whose manifest declares an addon module (e.g. a premium/bundled module) on a server whose license lacks that module; installing a marketplace app that later gained an addon requirement.
Common situations: License downgrade removed the module; app updated to require a new addon; community edition used to enable a premium app.
Related errors
- license-prevented
- invalid-license
- error-action-not-allowed
- error-action-not-allowed
- error-action-not-allowed
AI-assisted analysis of RocketChat/Rocket.Chat@f9d3ec372b (2026-08-12).
Data as JSON: /api/errors/9cafc33e00ad0a0a.
Report an issue: GitHub.