OrchardCMS/OrchardCore · error · Error

No url defined.

Error message

No url defined.

What it means

FetchHttpClient.send throws 'No url defined.' when the HttpRequest's url property is empty or undefined. Every outgoing SignalR HTTP request must carry a target URL. The library fails fast rather than letting fetch throw a more obscure error.

Solutions

  1. Pass a valid absolute or relative hub URL to withUrl(): `new HubConnectionBuilder().withUrl('/hubs/chat')`
  2. Log/inspect the URL before send and fail early if falsy
  3. Check configuration sources (env vars, appsettings) that supply the hub base URL

Example fix

// before
const hubUrl = config.hubBase + '/chat'; // config.hubBase undefined -> 'undefined/chat'
// after
const hubUrl = (config.hubBase ?? 'https://example.com') + '/chat';
if (!hubUrl) throw new Error('Hub URL not configured');
Defensive patterns

Strategy: validation

Validate before calling

if (!request?.url) throw new Error('request.url required');

Type guard

const hasUrl = (r) => typeof r?.url === 'string' && r.url.length > 0;

Try / catch

try { await client.send(request); } catch (e) { if (e.message === 'No url defined.') logConfigError(); }

Prevention

When it happens

Trigger: Creating an HttpRequest without a url; passing an empty string or undefined to HttpConnection constructor's url; a custom transport calling send() with a request built without the endpoint.

Common situations: Misconfigured hub URL from appsettings/environment (empty value); concatenating a base URL that is undefined so the result is 'undefined/negotiate' or ''; using connectAsync-style helpers where the hub name is misspelled.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/83b2bb30b914dc4b. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore.Modules/OrchardCore.SignalR/wwwroot/Scripts/signalr.js:609

            const requireFunc =  true ? require : 0;
            // Node needs EventListener methods on AbortController which our custom polyfill doesn't provide
            this._abortControllerType = requireFunc("abort-controller");
        }
        else {
            this._abortControllerType = AbortController;
        }
    }
    /** @inheritDoc */
    async send(request) {
        // Check that abort was not signaled before calling send
        if (request.abortSignal && request.abortSignal.aborted) {
            throw new AbortError();
        }
        if (!request.method) {
            throw new Error("No method defined.");
        }
        if (!request.url) {
            throw new Error("No url defined.");
        }
        const abortController = new this._abortControllerType();
        let error;
        // Hook our abortSignal into the abort controller
        if (request.abortSignal) {
            request.abortSignal.onabort = () => {
                abortController.abort();
                error = new AbortError();
            };
        }
        // If a timeout has been passed in, setup a timeout to call abort
        // Type needs to be any to fit window.setTimeout and NodeJS.setTimeout
        let timeoutId = null;
        if (request.timeout) {
            const msTimeout = request.timeout;
            timeoutId = setTimeout(() => {
                abortController.abort();
                this._logger.log(LogLevel.Warning, `Timeout from HTTP request.`);

View on GitHub (pinned to 4306c0717f)