microsoft/aspire · warning

Unexpected Vite config format. Falling back to original…

Error message

Unexpected Vite config format. Falling back to original configuration without Aspire HTTPS modifications.

What it means

Aspire's JavaScript hosting injects HTTPS development-certificate configuration into a project's vite.config by wrapping the exported config. When the generated script sees a vite.config default export whose shape is neither a function nor a plain object (e.g. defineConfig returned something unexpected, or an array form), it logs this console.warn and falls back to the original config untouched — meaning the Aspire HTTPS modifications are NOT applied.

Solutions

  1. Restructure vite.config so the default export is either a plain config object or a function returning the config — the two shapes Aspire recognizes.
  2. Verify no custom wrapper around defineConfig changes the exported value's type.
  3. If HTTPS config is intentionally handled elsewhere, the warning can be ignored, but confirm browser dev-server URLs still work with the AppHost endpoints.
  4. Update Vite/project templates if an outdated template produces the odd export shape.

Example fix

// before: exotic export shape
export default [...(somePluginConfig), defineConfig({ server: {} })];
// after: plain object (or function) export
export default defineConfig({ server: { /* ... */ } });
Defensive patterns

Strategy: validation

Validate before calling

// Validate the vite config default export shape before Aspire processes it.
import cfg from './vite.config';
const isFn = typeof cfg === 'function';
const isObj = typeof cfg === 'object' && cfg !== null && !Array.isArray(cfg);
if (!isFn && !isObj) throw new TypeError('vite.config default export must be a function or object');

Type guard

function isSupportedViteConfig(cfg) {
  return typeof cfg === 'function' || (typeof cfg === 'object' && cfg !== null);
}

Try / catch

// Since the injector only warns and falls back, watch for it in build output:
process.on('warning', () => {}); // or grep dev-server output for:
// 'Unexpected Vite config format' -> fix vite.config export shape

Prevention

When it happens

Trigger: addNpm/Vite app integration rewrites vite.config.* and evaluates the existing default export; the export is not a function and not a non-null object (primitive, null, or unusual defineConfig output), so the else branch warns and uses the config as-is.

Common situations: Hand-edited vite.config exporting an unsupported shape; older Vite templates or plugins altering the export; projects where 'defineConfig' is wrapped or re-exported in a way Aspire's wrapper does not recognize.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/ca0adaf7cbc38fc3. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.JavaScript/JavaScriptHostingExtensions.cs:109

        server: {
            ...innerConfig.server,
            https: innerConfig.server?.https ?? aspireHttpsConfig,
        }
    })

    let finalConfig = config
    try {
        if (typeof config === 'function') {
            finalConfig = defineConfig((cfg) => {
                let innerConfig = config(cfg)

                return wrapConfig(innerConfig)
            });
        } else if (typeof config === 'object' && config !== null) {
            let innerConfig = config
            finalConfig = defineConfig(wrapConfig(innerConfig))
        } else {
            console.warn('Unexpected Vite config format. Falling back to original configuration without Aspire HTTPS modifications.')
            finalConfig = config
        }
    } catch {
        console.warn('Error applying Aspire Vite configuration. Falling back to original configuration without Aspire HTTPS modifications.')
        finalConfig = config
    }

    export default finalConfig
    """;

    /// <summary>
    /// Adds a node application to the application model. Node should be available on the PATH.
    /// </summary>
    /// <param name="builder">The <see cref="IDistributedApplicationBuilder"/> to add the resource to.</param>
    /// <param name="name">The name of the resource.</param>
    /// <param name="appDirectory">The path to the directory containing the node application.</param>
    /// <param name="scriptPath">The path to the script relative to the app directory to run.</param>
    /// <returns>A reference to the <see cref="IResourceBuilder{T}"/>.</returns>

View on GitHub (pinned to 25830f84bd)