{"record":{"id":"54c1e1a2f16ea013","repo":"withastro/astro","slug":"server-address-unavailable-this-should-not-happen","errorCode":null,"errorMessage":"Server address unavailable, this should not happen. Open an issue.","messagePattern":"Server address unavailable, this should not happen\\. Open an issue\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/astro/src/assets/fonts/infra/remote-runtime-font-file-url-resolver.ts","lineNumber":53,"sourceCode":"\t\tif (!url.startsWith('/')) {\n\t\t\tif (this.#address) {\n\t\t\t\turl = new URL(url).pathname;\n\t\t\t} else {\n\t\t\t\treturn url;\n\t\t\t}\n\t\t}\n\t\tif (this.#address) {\n\t\t\tconst host =\n\t\t\t\tthis.#address.family === 'IPv6' ? `[${this.#address.address}]` : this.#address.address;\n\t\t\treturn `http://${host}:${this.#address.port}${url}`;\n\t\t}\n\t\t// Fallback when the server address was not available at module\n\t\t// load time (e.g. an adapter's dep optimizer pre-bundled the\n\t\t// font runtime before the HTTP server started listening, #17722).\n\t\tif (requestUrl) {\n\t\t\treturn `${requestUrl.origin}${url}`;\n\t\t}\n\t\tthrow new Error('Server address unavailable, this should not happen. Open an issue.');\n\t}\n}\n","sourceCodeStart":35,"sourceCodeEnd":56,"githubUrl":"https://github.com/withastro/astro/blob/3578d45d34226d63cff3d261c971c221de6794d2/packages/astro/src/assets/fonts/infra/remote-runtime-font-file-url-resolver.ts#L35-L56","documentation":"Astro's experimental Fonts API serves font files in dev through a Vite middleware and during prerendering through a temporary Node HTTP server; experimental_getFontFileURL() turns the internal font path into an absolute URL by prefixing it with that server's origin. The origin normally comes from an AddressInfo snapshot baked into the virtual module 'virtual:astro:assets/fonts/runtime/font-file-url-resolver' when it is generated/evaluated. This error means that snapshot was null (the module was evaluated before any HTTP server emitted 'listening', e.g. an adapter's dep optimizer pre-bundled the fonts runtime, astro #17722) AND the caller did not pass a requestUrl as the second argument, so no origin could be derived. Astro throws rather than guessing because a wrong origin would silently produce broken font links; the message asks for an issue because it marks a race the runtime believes it has covered. Note the throw is wrapped by createGetFontFileURL into an AstroError named 'FontFileUrlNotFound', so this text usually appears as the cause of that error.","triggerScenarios":"Calling experimental_getFontFileURL(url) with a single argument (no requestUrl) while RemoteRuntimeFontFileUrlResolver was constructed with address: null — i.e. in 'astro dev' or prerendering when the font runtime virtual module was evaluated before the dev server's 'listening' event (vite-plugin-fonts.ts only captures serverAddress on listening) or before the prerender temp server existed. Classic repro: an adapter (Cloudflare/Netlify-style on-demand adapters) whose Vite optimizeDeps pre-bundles the fonts runtime ahead of server startup (#17722), or calling the helper at module top level / outside a request context where Astro.url cannot be passed. Reachable only for a known root-relative font URL: for assetsPrefix (non-slash) URLs the resolver returns early, and unknown URLs return null ('FontFileUrlNotFound' without this cause).","commonSituations":"Using the experimental fonts config (fonts: [...] in astro.config) together with the <Font /> component or experimental_getFontFileURL in dev, especially with an on-demand adapter installed. Running an older Astro version from before the #17722 requestUrl fallback was added, or a stale Vite dep cache (node_modules/.vite) still holding a pre-bundle generated before the server bound. Calling the helper in middleware, module scope, or a setup hook where no request URL exists.","solutions":["Pass the request URL as the second argument: experimental_getFontFileURL(url, Astro.url). The resolver then derives the origin from requestUrl.origin and never needs the server address.","Update Astro to the latest release — the requestUrl fallback exists precisely for this race (#17722); older 5.x builds always threw in this situation.","Restart the dev server and delete node_modules/.vite (and the adapter's pre-bundle cache) so the font runtime virtual module is regenerated after the HTTP server is listening, re-baking a non-null address.","Only call experimental_getFontFileURL inside a request/render context (component frontmatter, API route), never at module top level where Astro.url is unavailable.","If it still reproduces with a requestUrl passed and current Astro, open an issue on the withastro/astro repo as the message requests — it indicates an unhandled module-evaluation/server-bind race in an adapter."],"exampleFix":"// before — single argument; relies on the dev-server address baked into the virtual module\nimport { experimental_getFontFileURL, fontData } from 'astro:assets/fonts/runtime';\nconst fileUrl = experimental_getFontFileURL(fontData.myFamily.regular[0].url);\n\n// after — pass the request URL so the origin is derived from it when the\n// server address was unavailable at module load time (#17722)\nconst fileUrl = experimental_getFontFileURL(fontData.myFamily.regular[0].url, Astro.url);","handlingStrategy":"validation","validationCode":"// Before calling, verify you are in a request context and pass its URL —\n// with a requestUrl present the resolver never reaches the throw.\nconst requestUrl = Astro.url;\nif (!(requestUrl instanceof URL)) {\n  throw new Error('experimental_getFontFileURL() must be called during a request, e.g. in component frontmatter');\n}\nconst fileUrl = experimental_getFontFileURL(fontData.myFamily.regular[0].url, requestUrl);","typeGuard":"function isRequestUrl(value: unknown): value is URL {\n  return value instanceof URL && /^https?:$/.test(value.protocol);\n}","tryCatchPattern":"import { isAstroError } from 'astro/errors';\n\ntry {\n  const fileUrl = experimental_getFontFileURL(fontUrl, Astro.url);\n} catch (err) {\n  if (isAstroError(err) && String((err.cause as Error)?.message ?? '').includes('Server address unavailable')) {\n    // The dev-server address race: fall back to rendering without the\n    // custom font file URL (or retry once the server is listening).\n  } else {\n    throw err;\n  }\n}","preventionTips":["Always pass Astro.url as the second argument to experimental_getFontFileURL, especially in dev and when an on-demand adapter is installed.","Call the helper only inside a request/render context (component frontmatter, endpoints), never at module top level or in startup hooks.","Keep Astro updated; the requestUrl fallback for this exact race (issue #17722) is absent in older 5.x releases.","After upgrading an adapter, clear Vite's dep cache (node_modules/.vite) so the fonts runtime is not served from a pre-bundle generated before the server bound.","Treat the 'experimental_' prefix literally: pin versions and wrap call sites so experimental API breakage cannot take down a production render."],"tags":["astro","fonts","experimental","dev-server","virtual-module","race-condition","adapter"],"backgroundTag":"server-address-unavailable","analyzedSha":"3578d45d34226d63cff3d261c971c221de6794d2","analyzedAt":"2026-08-21T18:22:53.330Z","contentChangedAt":"2026-08-21T18:22:53.330Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}