Skip to content

unstable_getResponseFromNextConfig does not resolve async function configs #92500

@TooTallNate

Description

@TooTallNate

Link to the code that reproduces this issue

https://github.com/vercel/next-config-fn-repro

To Reproduce

  1. Export an async function config from next.config.mjs (the standard (phase, ctx) => config pattern used by plugins like withSentry, withWorkflow, etc.):
// next.config.mjs
function withExamplePlugin(nextConfig) {
  return async (phase, { defaultConfig }) => {
    return { ...nextConfig };
  };
}

export default withExamplePlugin({
  async rewrites() {
    return [{ source: '/old', destination: '/new' }];
  },
});
  1. Use unstable_getResponseFromNextConfig to test rewrites/redirects:
import { unstable_getResponseFromNextConfig, getRewrittenUrl } from 'next/experimental/testing/server';

const nextConfig = (await import('./next.config.mjs')).default;
// typeof nextConfig === 'function'

const response = await unstable_getResponseFromNextConfig({ url: '/old', nextConfig });
getRewrittenUrl(response); // null — expected '/new'

Current vs. Expected behavior

Current: unstable_getResponseFromNextConfig passes the config directly to loadCustomRoutes, which accesses config.rewrites, config.redirects, etc. Since the config is a function (not an object), these properties are undefined and every route match returns null.

Expected: The utility should resolve function configs before passing them to loadCustomRoutes, the same way Next.js itself does at build time:

let resolved = nextConfig;
if (typeof resolved === 'function') {
  resolved = await resolved('phase-production-build', { defaultConfig: {} });
}

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
Next.js: 16.2.1-canary.24

Which area(s) are affected? (Select all that apply)

Testing utilities (next/experimental/testing/server)

Which stage(s) are affected? (Select all that apply)

Other (N/A — testing utility)

Additional context

The root cause is in next/dist/experimental/testing/server/config-testing-utils.js line 59:

const routes = await loadCustomRoutes(nextConfig);

loadCustomRoutes expects a plain config object. It immediately accesses config.assetPrefix, config.basePath, config.rewrites, etc.

This affects any project using Next.js config plugins that return async function wrappers — a common pattern across the ecosystem (@sentry/nextjs, @vercel/workflow, etc.).

Metadata

Metadata

Assignees

No one assigned

    Labels

    TestingRelated to testing with Next.js.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions