{"record":{"id":"b6b60717592ceb3f","repo":"dotnet/runtime","slug":"no-active-session-to-reconnect-b6b607","errorCode":null,"errorMessage":"No active session to reconnect","messagePattern":"No active session to reconnect","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/native/libs/System.Native.Browser/diagnostics/diagnostic-server.ts","lineNumber":78,"sourceCode":"    }\n    const bufferPtr: VoidPtr = buffer as any >>> 0 as any;\n    return wrapper.recv(bufferPtr, bytesToRead);\n}\n\nexport function ds_rt_websocket_close(clientSocket: number): number {\n    const wrapper = socketHandles.get(clientSocket);\n    if (!wrapper) {\n        return -1;\n    }\n    socketHandles.delete(clientSocket);\n    return wrapper.close();\n}\n\n// this will take over the existing connection to JS and send new advert message to WS client\n// use dotnet-dsrouter server-websocket -v trace\nexport function connectDSRouter(url: string): void {\n    if (!serverSession) {\n        throw new Error(\"No active session to reconnect\");\n    }\n\n    // make sure new sessions hit the new URL\n    urlOverride = url;\n\n    const oldWrapper = socketHandles.get(serverSession.clientSocket);\n    if (oldWrapper) {\n        oldWrapper.close();\n    }\n    const wrapper = createDiagConnectionWs(serverSession.clientSocket, url);\n    socketHandles.set(serverSession.clientSocket, wrapper);\n    wrapper.send(advertise());\n}\n\nexport function initializeDS() {\n    const loaderConfig = dotnetApi.getConfig();\n    const diagnosticPorts = \"DOTNET_DiagnosticPorts\";\n    loaderConfig.environmentVariables ??= {};","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/native/libs/System.Native.Browser/diagnostics/diagnostic-server.ts#L60-L96","documentation":"connectDSRouter() requires an existing JS diagnostic session to take over — it closes the JS-side wrapper for serverSession.clientSocket and re-opens it as a WebSocket toward a dotnet-dsrouter. Without serverSession there is no socket to migrate, so the call is meaningless and throws.","triggerScenarios":"Calling connectDSRouter(wsUrl) before any JS diagnostic session has been established (i.e. before serverSession was set by an advert message from the runtime). Calling it after the session already closed. Calling it in an environment where diagnostics were never enabled (DOTNET_DiagnosticPorts not set).","commonSituations":"Wiring up dotnet-dsrouter before triggering any diagnostic collection. Forgetting to enable DOTNET_DiagnosticPorts=js://ready via initializeDS. Calling connectDSRouter at app start instead of after the first session.","solutions":["Trigger a diagnostic session first (e.g. collectMetrics({}, true) at startup) so serverSession is populated.","Ensure initializeDS() ran, which sets DOTNET_DiagnosticPorts=js://ready in web environments so the runtime opens the JS socket.","Await Module.onDotnetReady and a first advert before calling connectDSRouter.","If you do not need JS sessions, do not call connectDSRouter — let the runtime open the WebSocket directly via its diagnostic port env var."],"exampleFix":"// before\nconnectDSRouter('ws://localhost:8181'); // serverSession undefined\n\n// after: seed a session at startup\nconst dotnetDiagnosticClient = (scenario) => ({ /* IDiagnosticClient */ });\ncollectMetrics({}, true); // populates serverSession\nawait dotnet.create();\nconnectDSRouter('ws://localhost:8181');","handlingStrategy":"validation","validationCode":"function hasServerSession(): boolean {\n  // serverSession is exported from diagnostic-server-js\n  // import { serverSession } from './diagnostic-server-js';\n  return !!serverSession;\n}\nif (hasServerSession()) connectDSRouter(wsUrl);","typeGuard":"function isSessionActive(s: unknown): s is { clientSocket: number } {\n  return !!s && typeof s === 'object' && typeof (s as any).clientSocket === 'number';\n}","tryCatchPattern":"try { connectDSRouter(url); } catch (e) {\n  if (/No active session/.test((e as Error).message)) {\n    await waitForFirstAdvert();\n    connectDSRouter(url);\n  } else throw e;\n}","preventionTips":["Register a startup diagnostic client so serverSession is populated at boot.","Ensure initializeDS() ran so DOTNET_DiagnosticPorts=js://ready is set.","Await Module.onDotnetReady plus the first advert before connectDSRouter.","Use dotnet-dsrouter logs to confirm the runtime opened its JS socket."],"tags":["diagnostics","dsrouter","session","websocket"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}