sveltejs/kit · error

DEV: Cannot use `${caller}` with a URL that does not resolve

Error message

DEV: Cannot use `${caller}` with a URL that does not resolve to a route within the app. Use `window.location = "${url}"` instead | PROD: ${caller}: invalid URL

What it means

Beyond being same-origin, navigation targets must resolve to a route defined in the app. get_navigation_intent() returns null when the resolved URL matches no route, so resolve_intent() throws to prevent the router from navigating into an undefined state. Production shows the compressed `${caller}: invalid URL` message.

Source

Thrown at packages/kit/src/runtime/client/client.js:2653

/**
 * @param {string | URL} url
 * @param {'goto' | 'pushState' | 'replaceState'} caller
 */
async function resolve_intent(url, caller) {
	const resolved = new URL(resolve_url(url));

	if (resolved.origin !== origin) {
		throw new Error(
			DEV
				? `Cannot use \`${caller}\` with an external URL. Use \`window.location = "${url}"\` instead`
				: `${caller}: invalid URL`
		);
	}

	const intent = await get_navigation_intent(resolved, false);

	if (!intent) {
		throw new Error(
			DEV
				? `Cannot use \`${caller}\` with a URL that does not resolve to a route within the app. Use \`window.location = "${url}"\` instead`
				: `${caller}: invalid URL`
		);
	}

	return intent;
}

/**
 * Allows you to navigate programmatically to a given route, with control over details such as whether scroll and focus are reset
 * (as they would be with a regular navigation) or preserved.
 *
 * Returns a Promise that resolves when SvelteKit navigates (or fails to navigate, in which case the promise rejects) or the state change has been applied.
 *
 * `goto` is intended for navigations to routes that belong to the app, and will reject if a route cannot be resolved.
 * For external URLs, use `window.location = url` to perform a full-page navigation instead of calling `goto(url)`.
 *

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Confirm the URL matches an existing route in src/routes
  2. Correct typos or create the missing +page.svelte route
  3. Use window.location for URLs genuinely outside the app's routes
  4. Check paths.base and trailing-slash configuration so the URL resolves correctly

Example fix

// before
await goto('/user/profile'); // no such route
// after
await goto('/user/[id]'.replace('[id]', userId)); // matches src/routes/user/[id]/+page.svelte
Defensive patterns

Strategy: validation

Validate before calling

// resolve against known route ids if exported, or use a simple allowlist
const knownRoutes = ['/', '/about', '/blog/[slug]'];
function resolvesToRoute(path) {
  return knownRoutes.some((r) => new RegExp('^' + r.replace(/\[.+?\]/g, '[^/]+') + '/?$').test(path));
}

Try / catch

try { await goto(url); } catch (e) { if (e.message.includes('invalid URL')) { window.location.assign(url); } else { throw e; } }

Prevention

When it happens

Trigger: goto('/nonexistent-path') where no route matches; pushState/replaceState with a path outside the app's route table; URL misses due to trailing-slash or base-path mismatches.

Common situations: Typos in route paths; navigating to routes removed after refactoring; deploying under a sub-path without configuring paths.base; dynamically built URLs from user data.

Related errors


AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02). Data as JSON: /api/errors/4c0325fb0f6f93c2. Report an issue: GitHub.