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

  1. Ensure the dynamically imported module has `export default { ... }` (or new Vue-extended constructor); in SFCs confirm the <script> block exports the component as default.
  2. If the module exports a named component, wrap it: () => import('./x').then(m => m.MyComponent).
  3. Log the resolved value: () => import('./x').then(m => { console.log(m); return m.default || m; }) to see what the loader actually returns.
  4. Verify the import path points to the component file, not a helpers/barrel module or wrong extension.
  5. 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

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


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)