dotnet/aspnetcore · error · Error
withCredentials option was not a 'boolean' or 'undefined'…
Error message
withCredentials option was not a 'boolean' or 'undefined' value
What it means
HttpConnection's constructor validates the withCredentials option: it must be a boolean or undefined. Any other type (string, number, null, object) is a programming error and is rejected immediately rather than being silently coerced, because withCredentials directly affects whether cookies/credentials cross origins and silent coercion would be a security hazard.
Solutions
- Pass a real boolean: withUrl(url, { withCredentials: true }).
- When reading from env/config, coerce explicitly: withCredentials: process.env.WITH_CREDENTIALS === 'true'.
- Omit the option entirely if you want the default (true).
- Add a TypeScript type assertion or runtime check that the value is boolean before constructing the connection.
Example fix
// before
const opts = { withCredentials: process.env.WITH_CREDENTIALS };
const conn = new signalR.HubConnectionBuilder().withUrl(url, opts).build();
// after
const opts = {
withCredentials: process.env.WITH_CREDENTIALS === "true",
};
const conn = new signalR.HubConnectionBuilder().withUrl(url, opts).build(); Defensive patterns
Strategy: type-guard
Validate before calling
function coerceWithCredentials(v: unknown): boolean | undefined {
if (v === undefined) return undefined;
if (typeof v === "boolean") return v;
throw new Error("withCredentials must be boolean or undefined");
} Type guard
function isValidWithCredentials(v: unknown): v is boolean | undefined {
return v === undefined || typeof v === "boolean";
} Try / catch
try {
new signalR.HubConnectionBuilder().withUrl(url, options).build();
} catch (e) {
if (e instanceof Error && /withCredentials/.test(e.message)) {
options.withCredentials = Boolean(options.withCredentials);
}
} Prevention
- Coerce env/config values to boolean at the config layer, not at the call site.
- Add a TS type for your options object that requires boolean|undefined for withCredentials.
- Write a unit test that string/'true'/null are rejected by your config validator.
When it happens
Trigger: Constructing new HttpConnection(url, { withCredentials: ... }) or new HubConnectionBuilder().withUrl(url, { withCredentials: ... }) with a non-boolean, non-undefined value. Most often a string "true", the number 1, or null passed by mistake from config.
Common situations: Config file or environment variable loaded as a string (process.env.WITH_CREDENTIALS === "true"), JSON that was parsed but the field came through as a string, a default value of null that the developer expected to be treated as undefined.
Related errors
- A valid url is required.
- Authentication refreshBeforeExpirationInMilliseconds must…
- The HubConnection url must be a valid url.
- Unknown log level
- Unknown passkey operation
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/79186f7106f001ff.
Report an issue: GitHub.
Appendix: source
Thrown at src/SignalR/clients/ts/signalr/src/HttpConnection.ts:95
public baseUrl: string;
public connectionId?: string;
public onreceive: ((data: string | ArrayBuffer) => void) | null;
public onclose: ((e?: Error) => void) | null;
private readonly _negotiateVersion: number = 1;
constructor(url: string, options: IHttpConnectionOptions = {}) {
Arg.isRequired(url, "url");
this._logger = createLogger(options.logger);
this.baseUrl = this._resolveUrl(url);
options = options || {};
options.logMessageContent = options.logMessageContent === undefined ? false : options.logMessageContent;
if (typeof options.withCredentials === "boolean" || options.withCredentials === undefined) {
options.withCredentials = options.withCredentials === undefined ? true : options.withCredentials;
} else {
throw new Error("withCredentials option was not a 'boolean' or 'undefined' value");
}
options.timeout = options.timeout === undefined ? 100 * 1000 : options.timeout;
let webSocketModule: any = null;
let eventSourceModule: any = null;
if (Platform.isNode && typeof require !== "undefined") {
// In order to ignore the dynamic require in webpack builds we need to do this magic
// @ts-ignore: TS doesn't know about these names
const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
webSocketModule = requireFunc("ws");
eventSourceModule = requireFunc("eventsource");
}
if (!Platform.isNode && typeof WebSocket !== "undefined" && !options.WebSocket) {
options.WebSocket = WebSocket;
} else if (Platform.isNode && !options.WebSocket) {
if (webSocketModule) {View on GitHub (pinned to 3600ca084e)