Astro Site Deploy Fail: Trace: RangeError: Maximum call stack size exceeded
fl0wo opened this issue · comments
Discord Msg Link:
https://discord.com/channels/983865673656705025/1068236979659092038/1217354520086974515
Hi guys, I'm having a problem with an Astro deploy :/
Trace: RangeError: Maximum call stack size exceeded
at String.replace ()
at routes.reduce.branches (file:///Users/x/WebstormProjects/starlight-signals/y/node_modules/sst/constructs/util/astroRouteCompressor.js:4:14)
I'm using: https://starlight.astro.build/
And was able to deploy my website using sst so far without issues.
Before I've added this dependency: https://github.com/HiDeoo/starlight-openapi
build ✅
preview ✅
sst deploy ✅
Now using starlight-openapi inside my astro page:
build ✅
preview ✅
sst deploy ❌
I guess has something to do with sst?
To reproduce the error is enough following this Astro integratio
n example:
https://starlight-openapi.vercel.app/getting-started/
In particular the line:
plugins: [
// Generate the OpenAPI documentation pages.
starlightOpenAPI([
Is what triggers the error while deploying, without this line, the deploy works as expected.
I'm atatching my sst.buildMeta.json file inside the dist folder when attempting the deployment.
sst.buildMeta.json
Thank you.
TLDR; Circular route matching pattern causing infinite loop
The OpenAPI plugin is injecting a very greedy route at the root of the site which conflicts with the root level matching route.
Ref: sst.buildMeta.json
{
"deploymentStrategy": "static",
"responseMode": "buffer",
"outputMode": "static",
"pageResolution": "directory",
"trailingSlash": "ignore",
"serverBuildOutputFile": "dist/server/entry.mjs",
"clientBuildOutputDir": "dist/",
"clientBuildVersionedSubDir": "_astro",
"routes": [
{
"route": "/_astro/ec.pjkke.css",
"type": "endpoint",
"pattern": "/^\\/_astro\\/ec\\.pjkke\\.css$/",
"prerender": true
},
{
"route": "/_astro/ec.sgewm.js",
"type": "endpoint",
"pattern": "/^\\/_astro\\/ec\\.sgewm\\.js$/",
"prerender": true
},
{
"route": "/_astro/[...slug]",
"type": "endpoint",
"pattern": "/^\\/_astro\\/.*?\\/?$/",
"prerender": true
},
{
"route": "/404",
"type": "page",
"pattern": "/^\\/404\\/?$/",
"prerender": true
},
{
"route": "/[...openapislug]",
"type": "page",
"pattern": "/^(?:\\/(.*?))?\\/?$/",
"prerender": true
},
{
"route": "/[...slug]",
"type": "page",
"pattern": "/^(?:\\/(.*?))?\\/?$/",
"prerender": true
}
],
"serverRoutes": []
}
Ref: astroRouteCompressor.js
function buildRouteTree(routes, level = 0) {
const routeTree = routes.reduce((tree, route) => {
const routePatternWithoutCaptureGroups = route.pattern
.replace(/\((?:\?:)?(.*?[^\\])\)/g, (_, content) => content.trim())
.replace(/\/\^/g, "")
.replace(/\$\//g, "");
const routeParts = routePatternWithoutCaptureGroups
.split(/(?=\\\/)/g)
.filter((part) => part !== "/^" && part !== "/$/");
tree.branches[routeParts[level]] = tree.branches[routeParts[level]] || {
branches: {},
nodes: [],
};
tree.branches[routeParts[level]].nodes.push(route);
return tree;
}, { branches: {}, nodes: [] });
for (const [key, branch] of Object.entries(routeTree.branches)) {
if (!branch.nodes.some((node) => node.prerender || node.type === "redirect")) {
delete routeTree.branches[key];
}
else if (branch.nodes.length > 1) {
routeTree.branches[key] = buildRouteTree(branch.nodes, level + 1);
branch.nodes = [];
}
}
return routeTree;
}