OrchardCMS/OrchardCore · error · Error
Invalid async component load result:
Error message
Invalid async component load result:
What it means
Vue 2's factory for async components (used by Vue.component(name, () => import(...)) and vue-router lazy routes) resolves the returned Promise and, after unwrapping an ES-module default export, requires the result to be an object (component options) or a function. This dev-mode check in vue.runtime.esm.js throws when the resolved value is neither, meaning the async loader did not return a component definition.
Solutions
- Ensure the dynamically imported module has `export default { ... }` (or new Vue-extended constructor); in SFCs confirm the <script> block exports the component as default.
- If the module exports a named component, wrap it: () => import('./x').then(m => m.MyComponent).
- Log the resolved value: () => import('./x').then(m => { console.log(m); return m.default || m; }) to see what the loader actually returns.
- Verify the import path points to the component file, not a helpers/barrel module or wrong extension.
- Check build tooling (webpack/babel/tsconfig) is compiling the SFC/component, not emitting an empty or unexpected module shape.
Example fix
// before
Vue.component('chart', () => import('./utils/chart-helpers'));
// after
Vue.component('chart', () => import('./components/Chart.vue')); // file has `export default { ... }` Defensive patterns
Strategy: type-guard
Validate before calling
async () => { const m = await import('./MyComp'); if (m && (typeof m === 'object' || typeof m === 'function') && (m.default || Object.keys(m).some(k => typeof m[k] === 'object' && m[k].template))) return; throw new Error('async import did not resolve to a Vue component'); } Type guard
function isComponentLike(v) { if (!v) return false; if (typeof v === 'function') return true; return typeof v === 'object' && (typeof v.render === 'function' || typeof v.template === 'string' || typeof v.setup === 'function'); } Try / catch
try { const comp = await loadFactory(); if (!isComponentLike(comp)) throw new TypeError('async component resolved to non-component: ' + typeof comp); Vue.component('x', comp); } catch (e) { console.error('Async component load failed', e); /* render fallback */ } Prevention
- Always `export default` the component in dynamically imported files
- Wrap named exports: () => import('./x').then(m => m.default || m.X)
- Spot-check lazy imports with a dev-time log of the resolved module
- Keep import paths pointing at the component file, not barrels/util modules
- Run lazy routes in a dev build early — Vue only asserts in dev mode
When it happens
Trigger: Calling Vue.component('x', () => import('./x')) or defining a router component as () => Promise, where the promise resolves to a non-component value: a module with no default export and no component-options export (e.g. a bare side-effect module), a string, null/undefined, a number, or a wrong namespace like () => import('./x.js').someHelper.
Common situations: Migrating to webpack/ESM where the component file lacks `export default`; a typo'd dynamic import path that resolves to a barrel file; TypeScript/Vue SFC compiled without default export; returning an object that is not component options (e.g. a loader wrapper or a library namespace); mixed Vue 2 codebases copied from Vue 3 patterns.
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/f7e90328b25c9950.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore.Modules/OrchardCore.Resources/wwwroot/Vendor/vue-2.7.16/vue.runtime.esm.js:3279
else {
throw err;
}
})
.then(function (comp) {
if (thisRequest !== pendingRequest && pendingRequest) {
return pendingRequest;
}
if (process.env.NODE_ENV !== 'production' && !comp) {
warn("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 (process.env.NODE_ENV !== 'production' && comp && !isObject(comp) && !isFunction(comp)) {
throw new Error("Invalid async component load result: ".concat(comp));
}
return comp;
})));
};
return function () {
var component = load();
return {
component: component,
delay: delay,
timeout: timeout,
error: errorComponent,
loading: loadingComponent
};
};
}
function createLifeCycle(hookName) {
return function (fn, target) {View on GitHub (pinned to 4306c0717f)