OrchardCMS/OrchardCore · error · Error
Invalid async component load result
Error message
Invalid async component load result: ${comp} What it means
Same Vue 2.7 async-component validation as the common.dev build, in the ESM browser build (vue.esm.browser.js): after the loader promise resolves and any ES-module default is unwrapped, the resulting value must be an object (options) or function (component). Otherwise the loader throws `Invalid async component load result: ${comp}`.
Solutions
- Make the loaded module export the component options object or function as its default export.
- Map the specific named export in the loader: () => import('./c.js').then(m => m.MyComponent).
- Confirm you're not passing a Vue 3-style component definition to Vue 2.7; adapt it to Vue 2 options API.
- Inspect the resolved module (console.log(m)) to see its actual export shape.
Example fix
// before
const AsyncComp = () => import('./widget.js'); // default export is a string template
// after
// widget.js: export default { template: '...', ... }
const AsyncComp = () => import('./widget.js').then(m => m.default); Defensive patterns
Strategy: type-guard
Validate before calling
function validAsyncComp(loader) {
return function () {
return loader().then(function (m) {
var c = (m && (m.__esModule || m[Symbol.toStringTag] === 'Module')) ? m.default : m;
if (!(c && (typeof c === 'object' || typeof c === 'function'))) {
throw new Error('Module did not export a Vue component');
}
return c;
});
};
} Type guard
function isVue2Component(v) { return v != null && typeof v === 'object' && ('render' in v || 'template' in v || typeof v === 'function'); } Try / catch
const AsyncComp = () => import('./widget.js')
.then(m => {
const c = m.default || m.Widget;
if (!c || (typeof c !== 'object' && typeof c !== 'function')) throw new Error('Bad export');
return c;
})
.catch(err => { console.error(err); return FallbackComponent; }); Prevention
- In ESM builds, rely on default exports for dynamically imported components.
- Avoid exporting plain strings/primitives from component modules.
- Don't feed Vue 3-style component definitions into a Vue 2.7 app.
- Wrap dynamic imports with a shape-checking helper used across the app.
When it happens
Trigger: Component factory () => import(...) resolving to a module without a component default export; resolving to a non-component value (string template, plain object of helpers, undefined from a misresolved path); interop failure so the wrapper object isn't unwrapped via __esModule/Symbol.toStringTag.
Common situations: Browser-native ESM builds importing .js component files that export named members only; typo'd import paths resolving to wrong files; mixing Vue 2 and Vue 3 component definitions (Vue 3 defineAsyncComponent/functional shapes rejected here).
Related errors
- Invalid async component load result:
- Invalid async component load result
- Invalid async component load result
- Invalid async component load result:
- Standalone host is missing a <div id="media-gallery"> mount…
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/b67f8c547e61cc88.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore.Modules/OrchardCore.Resources/wwwroot/Vendor/vue-2.7.16/vue.esm.browser.js:3884
else {
throw err;
}
})
.then((comp) => {
if (thisRequest !== pendingRequest && pendingRequest) {
return pendingRequest;
}
if (!comp) {
warn$2(`Async component loader resolved to undefined. ` +
`If you are using retry(), make sure to return its return value.`);
}
// interop module default
if (comp &&
(comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {
comp = comp.default;
}
if (comp && !isObject(comp) && !isFunction(comp)) {
throw new Error(`Invalid async component load result: ${comp}`);
}
return comp;
})));
};
return () => {
const component = load();
return {
component,
delay,
timeout,
error: errorComponent,
loading: loadingComponent
};
};
}
function createLifeCycle(hookName) {
return (fn, target = currentInstance) => {View on GitHub (pinned to 4306c0717f)