dotnet/aspnetcore · error · Error
Cannot resolve '${url}'.
Error message
Cannot resolve '${url}'. What it means
Thrown at HttpConnection.ts:676 inside _resolveUrl when the supplied url does not start with `http://` or `https://` AND `Platform.isBrowser` is false. Browsers can resolve relative URLs via an anchor tag (lines 684-688), but Node and other non-browser environments have no document to normalize against, so a non-absolute URL is unrecoverable.
Source
Thrown at src/SignalR/clients/ts/signalr/src/HttpConnection.ts:676
this._connectionStarted = false;
try {
if (this.onclose) {
this.onclose(error);
}
} catch (e) {
this._logger.log(LogLevel.Error, `HttpConnection.onclose(${error}) threw error '${e}'.`);
}
}
}
private _resolveUrl(url: string): string {
// startsWith is not supported in IE
if (url.lastIndexOf("https://", 0) === 0 || url.lastIndexOf("http://", 0) === 0) {
return url;
}
if (!Platform.isBrowser) {
throw new Error(`Cannot resolve '${url}'.`);
}
// Setting the url to the href propery of an anchor tag handles normalization
// for us. There are 3 main cases.
// 1. Relative path normalization e.g "b" -> "http://localhost:5000/a/b"
// 2. Absolute path normalization e.g "/a/b" -> "http://localhost:5000/a/b"
// 3. Networkpath reference normalization e.g "//localhost:5000/a/b" -> "http://localhost:5000/a/b"
const aTag = window.document.createElement("a");
aTag.href = url;
this._logger.log(LogLevel.Information, `Normalizing '${url}' to '${aTag.href}'.`);
return aTag.href;
}
private _resolveNegotiateUrl(url: string): string {
const negotiateUrl = new URL(url);
if (negotiateUrl.pathname.endsWith('/')) {View on GitHub (pinned to 294cab2f9b)
Solutions
- Pass a fully-qualified absolute URL in Node: `http://localhost:5000/hubs/chat`.
- Derive the URL from a base in Node: `new URL('/hubs/chat', process.env.BASE_URL).toString()`.
- For isomorphic code, branch on environment: in Node prepend the origin, in browser pass the relative path.
Example fix
// before (Node throws)
new HttpConnection('/hubs/chat');
// after
const base = process.env.HUB_BASE_URL || 'http://localhost:5000';
new HttpConnection(new URL('/hubs/chat', base).toString()); Defensive patterns
Strategy: validation
Validate before calling
function toAbsoluteUrl(maybeRelative) {
if (/^https?:\/\//i.test(maybeRelative)) return maybeRelative;
if (typeof window !== 'undefined') return new URL(maybeRelative, window.location.href).toString();
throw new Error(`Cannot resolve '${maybeRelative}' outside a browser; provide an absolute URL`);
}
const absUrl = toAbsoluteUrl(config.hubUrl); Type guard
function isAbsoluteHttpUrl(u: string): boolean {
return /^https?:\/\//i.test(u);
} Try / catch
// thrown synchronously from the constructor; wrap construction
let conn;
try { conn = new HttpConnection(url, options); }
catch (e) {
if (/Cannot resolve/.test(String(e))) {
conn = new HttpConnection(new URL(url, process.env.BASE_URL).toString(), options);
} else throw e;
} Prevention
- In Node/SSR always pass a fully-qualified URL with scheme.
- Use new URL(rel, base) to compute absolute URLs isomorphically.
- Reject empty/relative URLs in your config loader.
When it happens
Trigger: In Node, calling `new HttpConnection('/hubs/chat')` or `new HttpConnection('hubs/chat')` or `'localhost:5000/hub'` (missing scheme). Browser builds accept these because window.document.createElement('a') resolves them, but Node builds hit the throw at line 676.
Common situations: Sharing the same code/config between browser and Node (SSR, Next.js getServerSideProps, SSR-rendered React); reading a relative path from env config and using it in a Node worker; forgetting the protocol when hardcoding a localhost URL in tests.
Related errors
- No usable HttpClient found.
- 'WebSocket' is not supported in your environment.
- 'EventSource' is not supported in your environment.
- The HubConnection url must be a valid url.
- The 'HubConnectionBuilder.withUrl' method must be called bef
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/3898c18a3d66a2ee.
Report an issue: GitHub.