{"record":{"id":"79186f7106f001ff","repo":"dotnet/aspnetcore","slug":"withcredentials-option-was-not-a-boolean-or-und","errorCode":null,"errorMessage":"withCredentials option was not a 'boolean' or 'undefined' value","messagePattern":"withCredentials option was not a 'boolean' or 'undefined' value","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/SignalR/clients/ts/signalr/src/HttpConnection.ts","lineNumber":95,"sourceCode":"    public baseUrl: string;\n    public connectionId?: string;\n    public onreceive: ((data: string | ArrayBuffer) => void) | null;\n    public onclose: ((e?: Error) => void) | null;\n\n    private readonly _negotiateVersion: number = 1;\n\n    constructor(url: string, options: IHttpConnectionOptions = {}) {\n        Arg.isRequired(url, \"url\");\n\n        this._logger = createLogger(options.logger);\n        this.baseUrl = this._resolveUrl(url);\n\n        options = options || {};\n        options.logMessageContent = options.logMessageContent === undefined ? false : options.logMessageContent;\n        if (typeof options.withCredentials === \"boolean\" || options.withCredentials === undefined) {\n            options.withCredentials = options.withCredentials === undefined ? true : options.withCredentials;\n        } else {\n            throw new Error(\"withCredentials option was not a 'boolean' or 'undefined' value\");\n        }\n        options.timeout = options.timeout === undefined ? 100 * 1000 : options.timeout;\n\n        let webSocketModule: any = null;\n        let eventSourceModule: any = null;\n\n        if (Platform.isNode && typeof require !== \"undefined\") {\n            // In order to ignore the dynamic require in webpack builds we need to do this magic\n            // @ts-ignore: TS doesn't know about these names\n            const requireFunc = typeof __webpack_require__ === \"function\" ? __non_webpack_require__ : require;\n            webSocketModule = requireFunc(\"ws\");\n            eventSourceModule = requireFunc(\"eventsource\");\n        }\n\n        if (!Platform.isNode && typeof WebSocket !== \"undefined\" && !options.WebSocket) {\n            options.WebSocket = WebSocket;\n        } else if (Platform.isNode && !options.WebSocket) {\n            if (webSocketModule) {","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/SignalR/clients/ts/signalr/src/HttpConnection.ts#L77-L113","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst opts = { withCredentials: process.env.WITH_CREDENTIALS };\nconst conn = new signalR.HubConnectionBuilder().withUrl(url, opts).build();\n\n// after\nconst opts = {\n  withCredentials: process.env.WITH_CREDENTIALS === \"true\",\n};\nconst conn = new signalR.HubConnectionBuilder().withUrl(url, opts).build();","handlingStrategy":"type-guard","validationCode":"function coerceWithCredentials(v: unknown): boolean | undefined {\n  if (v === undefined) return undefined;\n  if (typeof v === \"boolean\") return v;\n  throw new Error(\"withCredentials must be boolean or undefined\");\n}","typeGuard":"function isValidWithCredentials(v: unknown): v is boolean | undefined {\n  return v === undefined || typeof v === \"boolean\";\n}","tryCatchPattern":"try {\n  new signalR.HubConnectionBuilder().withUrl(url, options).build();\n} catch (e) {\n  if (e instanceof Error && /withCredentials/.test(e.message)) {\n    options.withCredentials = Boolean(options.withCredentials);\n  }\n}","preventionTips":["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."],"tags":["configuration","validation","cors","credentials","typescript"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}