From 215972684964c6b78d5225f102a8ed9529b3bed5 Mon Sep 17 00:00:00 2001 From: devjiwonchoi Date: Wed, 15 Oct 2025 04:29:13 +0200 Subject: [PATCH 01/11] Improve Proxy invalid export error message --- Cargo.lock | 1 + crates/next-core/Cargo.toml | 1 + crates/next-core/src/middleware.rs | 77 +++++++++++++++---- packages/next/errors.json | 3 +- .../build/analysis/get-page-static-info.ts | 18 ++++- .../next/src/build/templates/middleware.ts | 18 ++++- 6 files changed, 98 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cca56b629f964..efa500f3d8c07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4322,6 +4322,7 @@ dependencies = [ "next-custom-transforms", "next-taskless", "once_cell", + "pathdiff", "percent-encoding", "qstring", "react_remove_properties", diff --git a/crates/next-core/Cargo.toml b/crates/next-core/Cargo.toml index 90f77cbcd556f..3b480e562a23d 100644 --- a/crates/next-core/Cargo.toml +++ b/crates/next-core/Cargo.toml @@ -15,6 +15,7 @@ workspace = true anyhow = { workspace = true } async-trait = { workspace = true } base64 = "0.21.0" +pathdiff = { workspace = true } either = { workspace = true, features = ["serde"] } once_cell = { workspace = true } qstring = { workspace = true } diff --git a/crates/next-core/src/middleware.rs b/crates/next-core/src/middleware.rs index 49c4a44c73eca..cb0cc43e6d0a7 100644 --- a/crates/next-core/src/middleware.rs +++ b/crates/next-core/src/middleware.rs @@ -1,4 +1,7 @@ +use std::env; + use anyhow::Result; +use pathdiff::diff_paths; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ResolvedVc, Vc, fxindexmap}; use turbo_tasks_fs::FileSystemPath; @@ -122,6 +125,30 @@ struct MiddlewareMissingExportIssue { file_path: FileSystemPath, } +impl MiddlewareMissingExportIssue { + fn get_relative_path(&self) -> String { + // Get relative path from current working directory (like process.cwd() in JavaScript) + let cwd = env::current_dir().ok(); + let file_path_str = self.file_path.path.as_str(); + let relative_path = if let Some(cwd) = cwd { + diff_paths(file_path_str, cwd) + .and_then(|p| p.to_str().map(|s| s.to_string())) + .unwrap_or_else(|| self.file_path.file_name().to_string()) + } else { + self.file_path.file_name().to_string() + }; + format!("./{}", relative_path) + } + + fn get_type_description(&self) -> &str { + if self.file_type.as_str() == "Proxy" { + "proxy (previously called middleware)" + } else { + "middleware" + } + } +} + #[turbo_tasks::value_impl] impl Issue for MiddlewareMissingExportIssue { #[turbo_tasks::function] @@ -139,23 +166,43 @@ impl Issue for MiddlewareMissingExportIssue { } #[turbo_tasks::function] - fn title(&self) -> Vc { - let file_name = self.file_path.file_name(); - - StyledString::Line(vec![ - StyledString::Text(rcstr!("The ")), - StyledString::Code(self.file_type.clone()), - StyledString::Text(rcstr!(" file \"")), - StyledString::Code(format!("./{}", file_name).into()), - StyledString::Text(rcstr!("\" must export a function named ")), - StyledString::Code(format!("`{}`", self.function_name).into()), - StyledString::Text(rcstr!(" or a default function.")), - ]) - .cell() + async fn title(&self) -> Result> { + let relative_path_str = self.get_relative_path(); + + // Only the first line goes in title to avoid formatIssue indentation + let title_text = format!( + "The file \"{}\" must export a function, either as a default export or as a named \ + \"{}\" export.", + relative_path_str, self.function_name + ); + + Ok(StyledString::Text(title_text.into()).cell()) } #[turbo_tasks::function] - fn description(&self) -> Vc { - Vc::cell(None) + async fn description(&self) -> Result> { + let relative_path_str = self.get_relative_path(); + let type_description = self.get_type_description(); + + // Rest of the message goes in description to avoid formatIssue indentation + let description_text = format!( + "This function is what Next.js runs for every request handled by this {}.\n\n\ + Why this happens:\n\ + - The file exists but doesn't export a function.\n\ + - The export is not a function (e.g., an object or constant).\n\ + - There's a syntax error preventing the export from being recognized.\n\n\ + To fix it:\n\ + - Check your \"{}\" file.\n\ + - Ensure it has either a default or \"{}\" function export.\n\ + - Restart the dev server if the error persists.\n\n\ + Learn more: https://nextjs.org/docs/messages/middleware-to-proxy", + type_description, + relative_path_str, + self.function_name + ); + + Ok(Vc::cell(Some( + StyledString::Text(description_text.into()).resolved_cell(), + ))) } } diff --git a/packages/next/errors.json b/packages/next/errors.json index 7563516b715a3..9b75d28575d13 100644 --- a/packages/next/errors.json +++ b/packages/next/errors.json @@ -900,5 +900,6 @@ "899": "Both \"%s\" and \"%s\" files are detected. Please use \"%s\" instead. Learn more: https://nextjs.org/docs/messages/middleware-to-proxy", "900": "Both %s file \"./%s\" and %s file \"./%s\" are detected. Please use \"./%s\" only. Learn more: https://nextjs.org/docs/messages/middleware-to-proxy", "901": "Invalid \"cacheHandlers\" provided, expected an object e.g. { default: '/my-handler.js' }, received %s", - "902": "Invalid handler fields configured for \"cacheHandlers\":\\n%s" + "902": "Invalid handler fields configured for \"cacheHandlers\":\\n%s", + "903": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy" } diff --git a/packages/next/src/build/analysis/get-page-static-info.ts b/packages/next/src/build/analysis/get-page-static-info.ts index bc01e7e856374..cbbd65a77874b 100644 --- a/packages/next/src/build/analysis/get-page-static-info.ts +++ b/packages/next/src/build/analysis/get-page-static-info.ts @@ -2,7 +2,7 @@ import type { NextConfig } from '../../server/config-shared' import type { RouteHas } from '../../lib/load-custom-routes' import { promises as fs } from 'fs' -import { basename } from 'path' +import { relative } from 'path' import { LRUCache } from '../../server/lib/lru-cache' import { extractExportedConstValue, @@ -329,7 +329,7 @@ function validateMiddlewareProxyExports({ return } - const fileName = isProxy ? 'proxy' : 'middleware' + const fileName = isProxy ? PROXY_FILENAME : MIDDLEWARE_FILENAME // Parse AST to get export info (since checkExports doesn't return middleware/proxy info) let hasDefaultExport = false @@ -396,9 +396,21 @@ function validateMiddlewareProxyExports({ (isMiddleware && hasMiddlewareExport) || (isProxy && hasProxyExport) + const relativeFilePath = `./${relative(process.cwd(), pageFilePath)}` + if (!hasValidExport) { throw new Error( - `The ${fileName === 'proxy' ? 'Proxy' : 'Middleware'} file "./${basename(pageFilePath)}" must export a function named \`${fileName}\` or a default function.` + `The file "${relativeFilePath}" must export a function, either as a default export or as a named "${fileName}" export.\n` + + `This function is what Next.js runs for every request handled by this ${fileName === 'proxy' ? 'proxy (previously called middleware)' : 'middleware'}.\n\n` + + `Why this happens:\n` + + `- The file exists but doesn't export a function.\n` + + `- The export is not a function (e.g., an object or constant).\n` + + `- There's a syntax error preventing the export from being recognized.\n\n` + + `To fix it:\n` + + `- Check your "${relativeFilePath}" file.\n` + + `- Ensure it has either a default or "${fileName}" function export.\n` + + `- Restart the dev server if the error persists.\n\n` + + `Learn more: https://nextjs.org/docs/messages/middleware-to-proxy` ) } } diff --git a/packages/next/src/build/templates/middleware.ts b/packages/next/src/build/templates/middleware.ts index 7526961fe65bc..f9024b3e062c5 100644 --- a/packages/next/src/build/templates/middleware.ts +++ b/packages/next/src/build/templates/middleware.ts @@ -19,8 +19,24 @@ const isProxy = page === '/proxy' || page === '/src/proxy' const handler = (isProxy ? mod.proxy : mod.middleware) || mod.default if (typeof handler !== 'function') { + const fileName = isProxy ? 'proxy' : 'middleware' + // Webpack starts the path with "." as relative, but Turbopack does not. + const resolvedRelativeFilePath = relativeFilePath.startsWith('.') + ? relativeFilePath + : `./${relativeFilePath}` + throw new Error( - `The ${isProxy ? 'Proxy' : 'Middleware'} file "${relativeFilePath.startsWith('.') ? relativeFilePath : `./${relativeFilePath}`}" must export a function named \`${isProxy ? 'proxy' : 'middleware'}\` or a default function.` + `The file "${resolvedRelativeFilePath}" must export a function, either as a default export or as a named "${fileName}" export.\n` + + `This function is what Next.js runs for every request handled by this ${fileName === 'proxy' ? 'proxy (previously called middleware)' : 'middleware'}.\n\n` + + `Why this happens:\n` + + `- The file exists but doesn't export a function.\n` + + `- The export is not a function (e.g., an object or constant).\n` + + `- There's a syntax error preventing the export from being recognized.\n\n` + + `To fix it:\n` + + `- Check your "${resolvedRelativeFilePath}" file.\n` + + `- Ensure it has either a default or "${fileName}" function export.\n` + + `- Restart the dev server if the error persists.\n\n` + + `Learn more: https://nextjs.org/docs/messages/middleware-to-proxy` ) } From faca60a9a4174c5abf2501bdf0f7bc5c7664f92f Mon Sep 17 00:00:00 2001 From: devjiwonchoi Date: Fri, 17 Oct 2025 21:12:39 +0200 Subject: [PATCH 02/11] Update test --- .../proxy-missing-export.test.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts b/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts index 61813a45ee11c..559666027cb53 100644 --- a/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts +++ b/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts @@ -2,8 +2,20 @@ import { nextTestSetup } from 'e2e-utils' import { join } from 'node:path' import { writeFile } from 'node:fs/promises' -const errorMessage = - 'The Proxy file "./proxy.ts" must export a function named `proxy` or a default function.' +const errorMessage = `The file "./proxy.ts" must export a function, either as a default export or as a named "proxy" export. +This function is what Next.js runs for every request handled by this proxy (previously called middleware). + +Why this happens: +- The file exists but doesn't export a function. +- The export is not a function (e.g., an object or constant). +- There's a syntax error preventing the export from being recognized. + +To fix it: +- Check your "./proxy.ts" file. +- Ensure it has either a default or "proxy" function export. +- Restart the dev server if the error persists. + +Learn more: https://nextjs.org/docs/messages/middleware-to-proxy` describe('proxy-missing-export', () => { const { next, isNextDev, skipped } = nextTestSetup({ From b5f67fa85f37562b72aea7376766d07c1dad50f1 Mon Sep 17 00:00:00 2001 From: devjiwonchoi Date: Fri, 17 Oct 2025 21:56:52 +0200 Subject: [PATCH 03/11] Add additional bullet for proxy Co-authored-by: Joseph --- crates/next-core/src/middleware.rs | 9 +++++++++ packages/next/src/build/analysis/get-page-static-info.ts | 3 +++ packages/next/src/build/templates/middleware.ts | 3 +++ .../proxy-missing-export/proxy-missing-export.test.ts | 1 + 4 files changed, 16 insertions(+) diff --git a/crates/next-core/src/middleware.rs b/crates/next-core/src/middleware.rs index cb0cc43e6d0a7..dc1128dd74125 100644 --- a/crates/next-core/src/middleware.rs +++ b/crates/next-core/src/middleware.rs @@ -184,10 +184,18 @@ impl Issue for MiddlewareMissingExportIssue { let relative_path_str = self.get_relative_path(); let type_description = self.get_type_description(); + let migration_bullet = if self.file_type.as_str() == "Proxy" { + "- You are migrating from `middleware` to `proxy`, but haven't updated the exported \ + function.\n" + } else { + "" + }; + // Rest of the message goes in description to avoid formatIssue indentation let description_text = format!( "This function is what Next.js runs for every request handled by this {}.\n\n\ Why this happens:\n\ + {}\ - The file exists but doesn't export a function.\n\ - The export is not a function (e.g., an object or constant).\n\ - There's a syntax error preventing the export from being recognized.\n\n\ @@ -197,6 +205,7 @@ impl Issue for MiddlewareMissingExportIssue { - Restart the dev server if the error persists.\n\n\ Learn more: https://nextjs.org/docs/messages/middleware-to-proxy", type_description, + migration_bullet, relative_path_str, self.function_name ); diff --git a/packages/next/src/build/analysis/get-page-static-info.ts b/packages/next/src/build/analysis/get-page-static-info.ts index cbbd65a77874b..30db844f6474a 100644 --- a/packages/next/src/build/analysis/get-page-static-info.ts +++ b/packages/next/src/build/analysis/get-page-static-info.ts @@ -403,6 +403,9 @@ function validateMiddlewareProxyExports({ `The file "${relativeFilePath}" must export a function, either as a default export or as a named "${fileName}" export.\n` + `This function is what Next.js runs for every request handled by this ${fileName === 'proxy' ? 'proxy (previously called middleware)' : 'middleware'}.\n\n` + `Why this happens:\n` + + (isProxy + ? "- You are migrating from `middleware` to `proxy`, but haven't updated the exported function.\n" + : '') + `- The file exists but doesn't export a function.\n` + `- The export is not a function (e.g., an object or constant).\n` + `- There's a syntax error preventing the export from being recognized.\n\n` + diff --git a/packages/next/src/build/templates/middleware.ts b/packages/next/src/build/templates/middleware.ts index f9024b3e062c5..d30f7d8098867 100644 --- a/packages/next/src/build/templates/middleware.ts +++ b/packages/next/src/build/templates/middleware.ts @@ -29,6 +29,9 @@ if (typeof handler !== 'function') { `The file "${resolvedRelativeFilePath}" must export a function, either as a default export or as a named "${fileName}" export.\n` + `This function is what Next.js runs for every request handled by this ${fileName === 'proxy' ? 'proxy (previously called middleware)' : 'middleware'}.\n\n` + `Why this happens:\n` + + (isProxy + ? "- You are migrating from `middleware` to `proxy`, but haven't updated the exported function.\n" + : '') + `- The file exists but doesn't export a function.\n` + `- The export is not a function (e.g., an object or constant).\n` + `- There's a syntax error preventing the export from being recognized.\n\n` + diff --git a/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts b/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts index 559666027cb53..4b9ad4debf45b 100644 --- a/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts +++ b/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts @@ -6,6 +6,7 @@ const errorMessage = `The file "./proxy.ts" must export a function, either as a This function is what Next.js runs for every request handled by this proxy (previously called middleware). Why this happens: +- You are migrating from \`middleware\` to \`proxy\`, but haven't updated the exported function. - The file exists but doesn't export a function. - The export is not a function (e.g., an object or constant). - There's a syntax error preventing the export from being recognized. From 4404f3f3504a3f2aca80e60bdc5d88346cd48b3f Mon Sep 17 00:00:00 2001 From: devjiwonchoi Date: Fri, 17 Oct 2025 21:58:13 +0200 Subject: [PATCH 04/11] Update errors.json --- packages/next/errors.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/next/errors.json b/packages/next/errors.json index 9b75d28575d13..740f4cc90e833 100644 --- a/packages/next/errors.json +++ b/packages/next/errors.json @@ -901,5 +901,6 @@ "900": "Both %s file \"./%s\" and %s file \"./%s\" are detected. Please use \"./%s\" only. Learn more: https://nextjs.org/docs/messages/middleware-to-proxy", "901": "Invalid \"cacheHandlers\" provided, expected an object e.g. { default: '/my-handler.js' }, received %s", "902": "Invalid handler fields configured for \"cacheHandlers\":\\n%s", - "903": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy" + "903": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", + "904": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy" } From dbdcfc5814defa889f23024940dc28327ab8df2b Mon Sep 17 00:00:00 2001 From: devjiwonchoi Date: Mon, 20 Oct 2025 19:13:36 -0700 Subject: [PATCH 05/11] Remove "Restart the dev server if the error persists." --- crates/next-core/src/middleware.rs | 3 +-- packages/next/errors.json | 4 +++- packages/next/src/build/analysis/get-page-static-info.ts | 3 +-- packages/next/src/build/templates/middleware.ts | 3 +-- .../app-dir/proxy-missing-export/proxy-missing-export.test.ts | 1 - 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/crates/next-core/src/middleware.rs b/crates/next-core/src/middleware.rs index dc1128dd74125..fe17fb9f699ab 100644 --- a/crates/next-core/src/middleware.rs +++ b/crates/next-core/src/middleware.rs @@ -201,8 +201,7 @@ impl Issue for MiddlewareMissingExportIssue { - There's a syntax error preventing the export from being recognized.\n\n\ To fix it:\n\ - Check your \"{}\" file.\n\ - - Ensure it has either a default or \"{}\" function export.\n\ - - Restart the dev server if the error persists.\n\n\ + - Ensure it has either a default or \"{}\" function export.\n\n\ Learn more: https://nextjs.org/docs/messages/middleware-to-proxy", type_description, migration_bullet, diff --git a/packages/next/errors.json b/packages/next/errors.json index 740f4cc90e833..86b9beb0920cd 100644 --- a/packages/next/errors.json +++ b/packages/next/errors.json @@ -902,5 +902,7 @@ "901": "Invalid \"cacheHandlers\" provided, expected an object e.g. { default: '/my-handler.js' }, received %s", "902": "Invalid handler fields configured for \"cacheHandlers\":\\n%s", "903": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", - "904": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy" + "904": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", + "905": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", + "906": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy" } diff --git a/packages/next/src/build/analysis/get-page-static-info.ts b/packages/next/src/build/analysis/get-page-static-info.ts index 30db844f6474a..a3d37846c65be 100644 --- a/packages/next/src/build/analysis/get-page-static-info.ts +++ b/packages/next/src/build/analysis/get-page-static-info.ts @@ -411,8 +411,7 @@ function validateMiddlewareProxyExports({ `- There's a syntax error preventing the export from being recognized.\n\n` + `To fix it:\n` + `- Check your "${relativeFilePath}" file.\n` + - `- Ensure it has either a default or "${fileName}" function export.\n` + - `- Restart the dev server if the error persists.\n\n` + + `- Ensure it has either a default or "${fileName}" function export.\n\n` + `Learn more: https://nextjs.org/docs/messages/middleware-to-proxy` ) } diff --git a/packages/next/src/build/templates/middleware.ts b/packages/next/src/build/templates/middleware.ts index d30f7d8098867..2129918b93b1d 100644 --- a/packages/next/src/build/templates/middleware.ts +++ b/packages/next/src/build/templates/middleware.ts @@ -37,8 +37,7 @@ if (typeof handler !== 'function') { `- There's a syntax error preventing the export from being recognized.\n\n` + `To fix it:\n` + `- Check your "${resolvedRelativeFilePath}" file.\n` + - `- Ensure it has either a default or "${fileName}" function export.\n` + - `- Restart the dev server if the error persists.\n\n` + + `- Ensure it has either a default or "${fileName}" function export.\n\n` + `Learn more: https://nextjs.org/docs/messages/middleware-to-proxy` ) } diff --git a/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts b/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts index 4b9ad4debf45b..f07df743188ef 100644 --- a/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts +++ b/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts @@ -14,7 +14,6 @@ Why this happens: To fix it: - Check your "./proxy.ts" file. - Ensure it has either a default or "proxy" function export. -- Restart the dev server if the error persists. Learn more: https://nextjs.org/docs/messages/middleware-to-proxy` From 52c8fcfb82f18c0db9b1c88008493d9f3061edce Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Mon, 20 Oct 2025 15:31:03 -0700 Subject: [PATCH 06/11] Cleanup Turbopack and error message --- crates/next-core/src/middleware.rs | 48 ++++--------------- packages/next/errors.json | 3 +- .../build/analysis/get-page-static-info.ts | 3 +- .../next/src/build/templates/middleware.ts | 3 +- .../proxy-missing-export.test.ts | 39 +++++++++++---- 5 files changed, 42 insertions(+), 54 deletions(-) diff --git a/crates/next-core/src/middleware.rs b/crates/next-core/src/middleware.rs index fe17fb9f699ab..56845fd72accf 100644 --- a/crates/next-core/src/middleware.rs +++ b/crates/next-core/src/middleware.rs @@ -1,7 +1,4 @@ -use std::env; - use anyhow::Result; -use pathdiff::diff_paths; use turbo_rcstr::{RcStr, rcstr}; use turbo_tasks::{ResolvedVc, Vc, fxindexmap}; use turbo_tasks_fs::FileSystemPath; @@ -125,30 +122,6 @@ struct MiddlewareMissingExportIssue { file_path: FileSystemPath, } -impl MiddlewareMissingExportIssue { - fn get_relative_path(&self) -> String { - // Get relative path from current working directory (like process.cwd() in JavaScript) - let cwd = env::current_dir().ok(); - let file_path_str = self.file_path.path.as_str(); - let relative_path = if let Some(cwd) = cwd { - diff_paths(file_path_str, cwd) - .and_then(|p| p.to_str().map(|s| s.to_string())) - .unwrap_or_else(|| self.file_path.file_name().to_string()) - } else { - self.file_path.file_name().to_string() - }; - format!("./{}", relative_path) - } - - fn get_type_description(&self) -> &str { - if self.file_type.as_str() == "Proxy" { - "proxy (previously called middleware)" - } else { - "middleware" - } - } -} - #[turbo_tasks::value_impl] impl Issue for MiddlewareMissingExportIssue { #[turbo_tasks::function] @@ -167,13 +140,9 @@ impl Issue for MiddlewareMissingExportIssue { #[turbo_tasks::function] async fn title(&self) -> Result> { - let relative_path_str = self.get_relative_path(); - - // Only the first line goes in title to avoid formatIssue indentation let title_text = format!( - "The file \"{}\" must export a function, either as a default export or as a named \ - \"{}\" export.", - relative_path_str, self.function_name + "{} is missing expected function export name", + self.file_type ); Ok(StyledString::Text(title_text.into()).cell()) @@ -181,10 +150,13 @@ impl Issue for MiddlewareMissingExportIssue { #[turbo_tasks::function] async fn description(&self) -> Result> { - let relative_path_str = self.get_relative_path(); - let type_description = self.get_type_description(); + let type_description = if self.file_type == "Proxy" { + "proxy (previously called middleware)" + } else { + "middleware" + }; - let migration_bullet = if self.file_type.as_str() == "Proxy" { + let migration_bullet = if self.file_type == "Proxy" { "- You are migrating from `middleware` to `proxy`, but haven't updated the exported \ function.\n" } else { @@ -200,12 +172,10 @@ impl Issue for MiddlewareMissingExportIssue { - The export is not a function (e.g., an object or constant).\n\ - There's a syntax error preventing the export from being recognized.\n\n\ To fix it:\n\ - - Check your \"{}\" file.\n\ - - Ensure it has either a default or \"{}\" function export.\n\n\ + - Ensure this file has either a default or \"{}\" function export.\n\n\ Learn more: https://nextjs.org/docs/messages/middleware-to-proxy", type_description, migration_bullet, - relative_path_str, self.function_name ); diff --git a/packages/next/errors.json b/packages/next/errors.json index 86b9beb0920cd..5b0bb64faae02 100644 --- a/packages/next/errors.json +++ b/packages/next/errors.json @@ -904,5 +904,6 @@ "903": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", "904": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", "905": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", - "906": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy" + "906": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", + "907": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Ensure this file has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy" } diff --git a/packages/next/src/build/analysis/get-page-static-info.ts b/packages/next/src/build/analysis/get-page-static-info.ts index a3d37846c65be..01314d1449e2e 100644 --- a/packages/next/src/build/analysis/get-page-static-info.ts +++ b/packages/next/src/build/analysis/get-page-static-info.ts @@ -410,8 +410,7 @@ function validateMiddlewareProxyExports({ `- The export is not a function (e.g., an object or constant).\n` + `- There's a syntax error preventing the export from being recognized.\n\n` + `To fix it:\n` + - `- Check your "${relativeFilePath}" file.\n` + - `- Ensure it has either a default or "${fileName}" function export.\n\n` + + `- Ensure this file has either a default or "${fileName}" function export.\n\n` + `Learn more: https://nextjs.org/docs/messages/middleware-to-proxy` ) } diff --git a/packages/next/src/build/templates/middleware.ts b/packages/next/src/build/templates/middleware.ts index 2129918b93b1d..376c63a8d4e61 100644 --- a/packages/next/src/build/templates/middleware.ts +++ b/packages/next/src/build/templates/middleware.ts @@ -36,8 +36,7 @@ if (typeof handler !== 'function') { `- The export is not a function (e.g., an object or constant).\n` + `- There's a syntax error preventing the export from being recognized.\n\n` + `To fix it:\n` + - `- Check your "${resolvedRelativeFilePath}" file.\n` + - `- Ensure it has either a default or "${fileName}" function export.\n\n` + + `- Ensure this file has either a default or "${fileName}" function export.\n` + `Learn more: https://nextjs.org/docs/messages/middleware-to-proxy` ) } diff --git a/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts b/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts index f07df743188ef..4c6d2c6b2b2ea 100644 --- a/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts +++ b/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts @@ -2,8 +2,7 @@ import { nextTestSetup } from 'e2e-utils' import { join } from 'node:path' import { writeFile } from 'node:fs/promises' -const errorMessage = `The file "./proxy.ts" must export a function, either as a default export or as a named "proxy" export. -This function is what Next.js runs for every request handled by this proxy (previously called middleware). +const errorMessage = `This function is what Next.js runs for every request handled by this proxy (previously called middleware). Why this happens: - You are migrating from \`middleware\` to \`proxy\`, but haven't updated the exported function. @@ -12,8 +11,7 @@ Why this happens: - There's a syntax error preventing the export from being recognized. To fix it: -- Check your "./proxy.ts" file. -- Ensure it has either a default or "proxy" function export. +- Ensure this file has either a default or "proxy" function export. Learn more: https://nextjs.org/docs/messages/middleware-to-proxy` @@ -34,14 +32,25 @@ describe('proxy-missing-export', () => { 'export function middleware() {}' ) + let cliOutput: string + if (isNextDev) { await next.start().catch(() => {}) // Use .catch() because Turbopack errors during compile and exits before runtime. await next.browser('/').catch(() => {}) - expect(next.cliOutput).toContain(errorMessage) + cliOutput = next.cliOutput + } else { + cliOutput = (await next.build()).cliOutput + } + + if (process.env.IS_TURBOPACK_TEST) { + expect(cliOutput).toContain(`./proxy.ts +Proxy is missing expected function export name +${errorMessage}`) } else { - const { cliOutput } = await next.build() - expect(cliOutput).toContain(errorMessage) + expect(cliOutput) + .toContain(`The file "./proxy.ts" must export a function, either as a default export or as a named "proxy" export. +${errorMessage}`) } await next.stop() @@ -106,16 +115,26 @@ describe('proxy-missing-export', () => { 'const proxy = () => {}; export { proxy as handler };' ) + let cliOutput: string + if (isNextDev) { await next.start().catch(() => {}) // Use .catch() because Turbopack errors during compile and exits before runtime. await next.browser('/').catch(() => {}) - expect(next.cliOutput).toContain(errorMessage) + cliOutput = next.cliOutput } else { - const { cliOutput } = await next.build() - expect(cliOutput).toContain(errorMessage) + cliOutput = (await next.build()).cliOutput } + if (process.env.IS_TURBOPACK_TEST) { + expect(cliOutput).toContain(`./proxy.ts +Proxy is missing expected function export name +${errorMessage}`) + } else { + expect(cliOutput) + .toContain(`The file "./proxy.ts" must export a function, either as a default export or as a named "proxy" export. +${errorMessage}`) + } await next.stop() }) }) From 9171a98a62ee7d20964a8b101cbdad52a3eab57b Mon Sep 17 00:00:00 2001 From: devjiwonchoi Date: Mon, 20 Oct 2025 22:54:31 -0700 Subject: [PATCH 07/11] Fix errors.json and new line --- packages/next/errors.json | 3 ++- packages/next/src/build/templates/middleware.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/next/errors.json b/packages/next/errors.json index 5b0bb64faae02..696091a222846 100644 --- a/packages/next/errors.json +++ b/packages/next/errors.json @@ -905,5 +905,6 @@ "904": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", "905": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", "906": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", - "907": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Ensure this file has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy" + "907": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Ensure this file has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", + "908": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Ensure this file has either a default or \"%s\" function export.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy" } diff --git a/packages/next/src/build/templates/middleware.ts b/packages/next/src/build/templates/middleware.ts index 376c63a8d4e61..2637bd64dffaa 100644 --- a/packages/next/src/build/templates/middleware.ts +++ b/packages/next/src/build/templates/middleware.ts @@ -36,7 +36,7 @@ if (typeof handler !== 'function') { `- The export is not a function (e.g., an object or constant).\n` + `- There's a syntax error preventing the export from being recognized.\n\n` + `To fix it:\n` + - `- Ensure this file has either a default or "${fileName}" function export.\n` + + `- Ensure this file has either a default or "${fileName}" function export.\n\n` + `Learn more: https://nextjs.org/docs/messages/middleware-to-proxy` ) } From 3bb7709b028451f7f7763eb47e31c25a90d292dc Mon Sep 17 00:00:00 2001 From: devjiwonchoi Date: Tue, 21 Oct 2025 09:53:56 -0700 Subject: [PATCH 08/11] test: dev-turbo logs on browser only not terminal --- .../app-dir/proxy-missing-export/proxy-missing-export.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts b/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts index 4c6d2c6b2b2ea..f3a0c14514dec 100644 --- a/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts +++ b/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts @@ -43,7 +43,8 @@ describe('proxy-missing-export', () => { cliOutput = (await next.build()).cliOutput } - if (process.env.IS_TURBOPACK_TEST) { + // TODO: Investigate why in dev-turbo, the error is shown in the browser console, not CLI output. + if (process.env.IS_TURBOPACK_TEST && !isNextDev) { expect(cliOutput).toContain(`./proxy.ts Proxy is missing expected function export name ${errorMessage}`) From afac100eff149d328a806b8e78187b06700e23bb Mon Sep 17 00:00:00 2001 From: Jiwon Choi Date: Tue, 21 Oct 2025 10:15:15 -0700 Subject: [PATCH 09/11] test: dev-turbo logs on browser only not terminal --- .../app-dir/proxy-missing-export/proxy-missing-export.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts b/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts index f3a0c14514dec..92faf1c94e5b2 100644 --- a/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts +++ b/test/e2e/app-dir/proxy-missing-export/proxy-missing-export.test.ts @@ -127,7 +127,8 @@ ${errorMessage}`) cliOutput = (await next.build()).cliOutput } - if (process.env.IS_TURBOPACK_TEST) { + // TODO: Investigate why in dev-turbo, the error is shown in the browser console, not CLI output. + if (process.env.IS_TURBOPACK_TEST && !isNextDev) { expect(cliOutput).toContain(`./proxy.ts Proxy is missing expected function export name ${errorMessage}`) From b293ddd0d0f4dc2568ced7065d4a62c3937c4d76 Mon Sep 17 00:00:00 2001 From: Jiwon Choi Date: Tue, 21 Oct 2025 10:22:54 -0700 Subject: [PATCH 10/11] remove pathdiff Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> --- crates/next-core/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/next-core/Cargo.toml b/crates/next-core/Cargo.toml index 3b480e562a23d..90f77cbcd556f 100644 --- a/crates/next-core/Cargo.toml +++ b/crates/next-core/Cargo.toml @@ -15,7 +15,6 @@ workspace = true anyhow = { workspace = true } async-trait = { workspace = true } base64 = "0.21.0" -pathdiff = { workspace = true } either = { workspace = true, features = ["serde"] } once_cell = { workspace = true } qstring = { workspace = true } From 5923a411f9da6511ee2d4813fc38db31e46cadbf Mon Sep 17 00:00:00 2001 From: devjiwonchoi Date: Tue, 21 Oct 2025 12:05:27 -0700 Subject: [PATCH 11/11] Update errors.json --- packages/next/errors.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/next/errors.json b/packages/next/errors.json index 696091a222846..cbe2d5256c427 100644 --- a/packages/next/errors.json +++ b/packages/next/errors.json @@ -901,10 +901,5 @@ "900": "Both %s file \"./%s\" and %s file \"./%s\" are detected. Please use \"./%s\" only. Learn more: https://nextjs.org/docs/messages/middleware-to-proxy", "901": "Invalid \"cacheHandlers\" provided, expected an object e.g. { default: '/my-handler.js' }, received %s", "902": "Invalid handler fields configured for \"cacheHandlers\":\\n%s", - "903": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", - "904": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", - "905": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", - "906": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Check your \"%s\" file.\\n- Ensure it has either a default or \"%s\" function export.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", - "907": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Ensure this file has either a default or \"%s\" function export.\\n- Restart the dev server if the error persists.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy", - "908": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Ensure this file has either a default or \"%s\" function export.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy" + "903": "The file \"%s\" must export a function, either as a default export or as a named \"%s\" export.\\nThis function is what Next.js runs for every request handled by this %s.\\n\\nWhy this happens:\\n%s- The file exists but doesn't export a function.\\n- The export is not a function (e.g., an object or constant).\\n- There's a syntax error preventing the export from being recognized.\\n\\nTo fix it:\\n- Ensure this file has either a default or \"%s\" function export.\\n\\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy" }