withastro/astro · error · Error

Please use Astro.url instead.

Error message

Please use Astro.url instead.

What it means

In local development the Netlify adapter fabricates a mock Netlify Context for each request (getLocalDevNetlifyContext). Its url property is a getter that always throws: in Astro the request URL is exposed as Astro.url, and the stub exists to fail fast when Netlify Functions code reads context.url inside the Astro dev server.

Solutions

  1. Use Astro.url (or Astro.request.url / context.request.url in middleware) instead of context.url
  2. If you must keep Netlify-specific code, wrap the access in try/catch with an Astro.url fallback
  3. Reserve context usage for fields Astro does not mirror (waitUntil, site, deploy) and read URL-like data from Astro APIs

Example fix

// before
const url = locals.runtime.context.url;
// after
const url = Astro.url;
Defensive patterns

Strategy: fallback

Validate before calling

// Before reading the Netlify Context in shared code, branch on the dev context:
const ctx = locals.runtime?.context;
const isLocalDev = ctx?.deploy?.context === 'dev';
const url = isLocalDev ? Astro.url : ctx!.url; // dev stub throws; prod context is real

Type guard

function safeNetlifyUrl(context: any, fallback: URL): URL {
  try {
    return context.url;
  } catch {
    return fallback;
  }
}

Try / catch

let url: URL;
try {
  url = locals.runtime.context.url;
} catch {
  url = Astro.url; // local-dev stub always throws
}

Prevention

When it happens

Trigger: Reading locals.runtime.context.url (or destructuring { url } from the Netlify Context) in a page, endpoint, or middleware while running astro dev / netlify dev with the Netlify adapter.

Common situations: Copy-pasted Netlify Functions code where context.url is idiomatic; shared libraries that feature-detect context.url by touching it; code that works in a deployed function but is exercised locally for the first time.

Related errors


AI-assisted analysis of withastro/astro@3578d45d34 (2026-08-18). Data as JSON: /api/errors/6de4a1a4166f1e2e. Report an issue: GitHub.

Appendix: source

Thrown at packages/integrations/netlify/src/index.ts:556

				// Import Deno polyfill for `process.env` at the top of the file
				js: 'import process from "node:process";',
			},
		});
	}

	function getLocalDevNetlifyContext(req: IncomingMessage): Context {
		const isHttps = req.headers['x-forwarded-proto'] === 'https';
		const parseBase64JSON = <T = unknown>(header: string): T | undefined => {
			if (typeof req.headers[header] === 'string') {
				try {
					return JSON.parse(Buffer.from(req.headers[header] as string, 'base64').toString('utf8'));
				} catch {}
			}
		};

		const context: Context = {
			get url(): never {
				throw new Error('Please use Astro.url instead.');
			},
			// The dev server is a long running process, so promises will run even with a noop
			waitUntil: () => {},
			account: parseBase64JSON('x-nf-account-info') ?? {
				id: 'mock-netlify-account-id',
			},
			deploy: {
				context: 'dev',
				id:
					typeof req.headers['x-nf-deploy-id'] === 'string'
						? req.headers['x-nf-deploy-id']
						: 'mock-netlify-deploy-id',
				published: false,
			},
			site: parseBase64JSON('x-nf-site-info') ?? {
				id: 'mock-netlify-site-id',
				name: 'mock-netlify-site.netlify.app',
				url: `${isHttps ? 'https' : 'http'}://localhost:${isRunningInNetlify ? 8888 : 4321}`,

View on GitHub (pinned to 3578d45d34)