From ed9fc61c103fa415a3e85ca659b90c7a42a03a72 Mon Sep 17 00:00:00 2001 From: Domitrius Clark Date: Wed, 7 Oct 2026 13:05:27 -0400 Subject: [PATCH 1/2] fix(dev): use URL separators for static file paths getStatic built the forwarded URL from path.relative, which yields backslashes on Windows. @fastify/static 10.1.4 added a path spelling guard that stats the joined path, finds the file under a different spelling, and returns 403. Normalize to forward slashes. --- src/utils/proxy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/proxy.ts b/src/utils/proxy.ts index 2db347e4b9c..7e9ad96de8c 100644 --- a/src/utils/proxy.ts +++ b/src/utils/proxy.ts @@ -40,6 +40,7 @@ import { fileExistsAsync, isFileAsync } from '../lib/fs.js' import { getFormHandler } from '../lib/functions/form-submissions-handler.js' import { DEFAULT_FUNCTION_URL_EXPRESSION } from '../lib/functions/registry.js' import { initializeProxy as initializeImageProxy, isImageRequest } from '../lib/images/proxy.js' +import { normalizeBackslash } from '../lib/path.js' import { NETLIFYDEVLOG, @@ -150,7 +151,7 @@ const getStatic = async function (pathname: string, publicFolder: string) { return false } - return `/${path.relative(publicFolder, file)}` + return `/${normalizeBackslash(path.relative(publicFolder, file))}` } const isEndpointExists = async function (endpoint: string, origin: string) { From 8f5a6d3b8c81840c46d39c903140c23bdeb5bd46 Mon Sep 17 00:00:00 2001 From: Domitrius Clark Date: Wed, 7 Oct 2026 14:03:40 -0400 Subject: [PATCH 2/2] fix(dev): split on path.sep instead of replacing backslashes A POSIX filename may contain a literal backslash. Splitting on the OS separator only rewrites Windows separators. --- src/utils/proxy.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/utils/proxy.ts b/src/utils/proxy.ts index 7e9ad96de8c..0a066360858 100644 --- a/src/utils/proxy.ts +++ b/src/utils/proxy.ts @@ -40,7 +40,6 @@ import { fileExistsAsync, isFileAsync } from '../lib/fs.js' import { getFormHandler } from '../lib/functions/form-submissions-handler.js' import { DEFAULT_FUNCTION_URL_EXPRESSION } from '../lib/functions/registry.js' import { initializeProxy as initializeImageProxy, isImageRequest } from '../lib/images/proxy.js' -import { normalizeBackslash } from '../lib/path.js' import { NETLIFYDEVLOG, @@ -151,7 +150,7 @@ const getStatic = async function (pathname: string, publicFolder: string) { return false } - return `/${normalizeBackslash(path.relative(publicFolder, file))}` + return `/${path.relative(publicFolder, file).split(path.sep).join('/')}` } const isEndpointExists = async function (endpoint: string, origin: string) {