ajaxorg/ace · error · Error
couldn't load module " + theme + " or it didn't call define
Error message
couldn't load module " + theme + " or it didn't call define
What it means
VirtualRenderer throws this Error when the theme module loaded asynchronously either failed to load or loaded without defining the expected API (a cssClass property). After $theme.loadModule resolves via afterLoad, a falsy module or a module missing cssClass means the theme script never registered itself (e.g., never called define).
Source
Thrown at src/virtual_renderer.js:2043
this.$themeId = theme;
_self._dispatchEvent('themeChange',{theme:theme});
if (!theme || typeof theme == "string") {
// @ts-ignore
var moduleName = theme || this.$options.theme.initialValue;
config.loadModule(["theme", moduleName], afterLoad);
} else {
afterLoad(theme);
}
/**
* @param {Theme} module
*/
function afterLoad(module) {
if (_self.$themeId != theme)
return cb && cb();
if (!module || !module.cssClass)
throw new Error("couldn't load module " + theme + " or it didn't call define");
if (module.$id)
_self.$themeId = module.$id;
dom.importCssString(
module.cssText,
module.cssClass,
_self.container
);
if (_self.theme)
dom.removeCssClass(_self.container, _self.theme.cssClass);
/**@type {any}*/
var padding = "padding" in module ? module.padding
: "padding" in (_self.theme || {}) ? 4 : _self.$padding;
if (_self.$padding && padding != _self.$padding)
_self.setPadding(padding);
if (_self.$gutterLayer) {
var showGutterCursor = module["$showGutterCursorMarker"];
if (showGutterCursor && !_self.$gutterLayer.$showCursorMarker) {View on GitHub (pinned to 2c1eddc392)
Solutions
- Verify the theme name/path exists, e.g. ace/theme/twilight — check the lib/ace/theme directory or CDN
- Check the browser network/console for 404s or CSP blocks on the theme script
- If self-hosting, configure the loader/basePath so 'ace/theme/x' resolves to the real theme file
- Ensure the theme module is included in your bundle or set the theme to a known-good built-in like 'ace/theme/textmate'
Example fix
// before
editor.setTheme('ace/theme/monokai_dark'); // doesn't exist
// after
editor.setTheme('ace/theme/monokai'); Defensive patterns
Strategy: fallback
Validate before calling
var themeName = 'ace/theme/monokai';
if (!/^ace\/theme\/[\w-]+$/.test(themeName)) throw new Error('bad theme name');
// verify availability if using ace's config: ace.config.loadModule(themeName, function(m){ if(!m) fallback(); }); Type guard
function isLoadedTheme(m) { return m && typeof m === 'object' && typeof m.cssClass === 'string' && m.cssClass.length > 0; } Try / catch
try {
renderer.setTheme('ace/theme/mytheme');
} catch (e) {
if (/couldn't load module/.test(e.message)) renderer.setTheme('ace/theme/textmate');
else throw e;
} Prevention
- Use exact built-in theme names (twilight, monokai, textmate, ...)
- When self-hosting, keep ace/theme/* files next to the core and set basePath correctly
- Check DevTools network tab for 404s on theme scripts after setTheme
- Pin ace and its themes to the same version
When it happens
Trigger: renderer.setTheme('ace/theme/Name') where the theme file does not exist at the resolved path, the CDN/network request fails, or the theme script is an old/incorrect build that doesn't call define() to export {cssClass, cssText}.
Common situations: Typo in theme name ('solarized_dark' vs 'solarized_dark'), self-hosting ace files with a broken path mapping for ace/theme/*, ad blockers or CSP blocking the theme script, or bundling ace without its theme modules.
AI-assisted analysis of ajaxorg/ace@2c1eddc392 (2026-08-30).
Data as JSON: /api/errors/de9b43307dc9a146.
Report an issue: GitHub.