laurent22/joplin · error · Error
All plugins must have a function default export
Error message
All plugins must have a function default export
What it means
Thrown by the CodeMirror 6 PluginLoader when a content script's evaluated module exports either no default or a default that is not a function. The loader contract (see addScript at line 137) requires every CodeMirror content script to export a default function that receives a context object { postMessage, pluginId, contentScriptId } and returns the plugin descriptor. This mirrors Joplin's content-script API for the CodeMirror editor.
Source
Thrown at packages/editor/CodeMirror/pluginApi/PluginLoader.ts:139
styleContainer.appendChild(style);
}
this.pluginScriptsContainer.appendChild(styleContainer);
};
this.pluginRemovalCallbacks[contentScriptToId(plugin)] = () => {
for (const callback of onRemoveCallbacks) {
callback();
}
this.loadedContentScriptIds = this.loadedContentScriptIds.filter(id => {
return id !== contentScriptToId(plugin);
});
};
addScript(async exports => {
if (!exports?.default || !(typeof exports.default === 'function')) {
throw new Error('All plugins must have a function default export');
}
const context = {
postMessage: plugin.postMessageHandler,
pluginId: plugin.pluginId,
contentScriptId: plugin.contentScriptId,
};
const loadedPlugin = exports.default(context) ?? {};
loadedPlugin.plugin?.(this.editor);
if (loadedPlugin.codeMirrorOptions) {
for (const key in loadedPlugin.codeMirrorOptions) {
this.editor.setOption(key, loadedPlugin.codeMirrorOptions[key]);
}
}
if (loadedPlugin.assets) {View on GitHub (pinned to 2654b33620)
Solutions
- Ensure the content script entry has exactly: export default (context) => { return { plugin, assets, codeMirrorOptions }; }.
- Check the plugin's webpack output config uses libraryTarget: 'commonjs' and libraryExport: 'default' for extra scripts (see resolveExtraScriptPath in webpack.config.js).
- Inspect the built JS in /dist to confirm module.exports.default is a function.
- If migrating from CM5, rewrite the entry to the function-default contract.
Example fix
// before (content script)
export const plugin = (editor) => { /* ... */ };
// after
export default ({ postMessage, pluginId, contentScriptId }) => {
return {
plugin: (editor) => { /* ... */ },
};
}; Defensive patterns
Strategy: type-guard
Validate before calling
// Validate the content script's default export shape in plugin tests
const exports = require('./src/index');
if (typeof exports.default !== 'function') {
throw new Error('Content script must export a default function');
} Type guard
function isValidContentScript(exports) {
return !!exports && typeof exports.default === 'function';
} Try / catch
try {
loader.setPlugins(contentScripts);
} catch (e) {
if (/function default export/.test(e.message)) {
// flag the offending plugin to the user, skip loading it
} else throw e;
} Prevention
- Always author content scripts as: export default (ctx) => ({ ... }).
- Set webpack libraryTarget: 'commonjs', libraryExport: 'default' for extra scripts.
- Inspect /dist output to confirm module.exports.default is a function before packaging.
When it happens
Trigger: The content script's bundled entry exports a named export instead of default; the default export is an object or class instance rather than a function; the script failed to assign module.exports.default due to a bundler misconfiguration (e.g. libraryTarget not set to produce a default export); the script threw before assigning exports.
Common situations: Plugin author wrote `export const plugin = ...` instead of `export default ...`; webpack libraryTarget/commonjs misconfiguration in the plugin's extra-script config; the content script was transpiled such that default is wrapped (e.g. __esModule default re-export); a port from CodeMirror 5 that used a different export shape.
Related errors
- Non-inline asset missing required property "name"
- Non-css assets are not supported by the CodeMirror 6 editor.
- Plugin assets must have property "mime" set to "text/css" or
- Cannot find library ${library}
- No text editor is defined. Please set it using `config edito
AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12).
Data as JSON: /api/errors/5c8ebbb733b587c6.
Report an issue: GitHub.