{"record":{"id":"822d9aca775761fa","repo":"dotnet/runtime","slug":"no-active-js-diagnostic-session-822d9a","errorCode":null,"errorMessage":"No active JS diagnostic session","messagePattern":"No active JS diagnostic session","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mono/browser/runtime/diagnostics/dotnet-cpu-profiler.ts","lineNumber":14,"sourceCode":"// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nimport type { DiagnosticCommandOptions } from \"../types\";\n\nimport { commandStopTracing, commandSampleProfiler } from \"./client-commands\";\nimport { loaderHelpers, Module, runtimeHelpers } from \"./globals\";\nimport { serverSession, setupJsClient } from \"./diagnostics-js\";\nimport { IDiagnosticSession } from \"./common\";\n\nexport function collectCpuSamples (options?:DiagnosticCommandOptions):Promise<Uint8Array[]> {\n    if (!options) options = {};\n    if (!serverSession) {\n        throw new Error(\"No active JS diagnostic session\");\n    }\n    if (!runtimeHelpers.config.environmentVariables![\"DOTNET_WasmPerformanceInstrumentation\"]) {\n        throw new Error(\"method instrumentation is not enabled, please enable it with WasmPerformanceInstrumentation MSBuild property\");\n    }\n\n    const onClosePromise = loaderHelpers.createPromiseController<Uint8Array[]>();\n    function onSessionStart (session: IDiagnosticSession): void {\n        // stop tracing after period of monitoring\n        Module.safeSetTimeout(() => {\n            session.sendCommand(commandStopTracing(session.session_id));\n        }, 1000 * (options?.durationSeconds ?? 60));\n    }\n\n    setupJsClient({\n        onClosePromise:onClosePromise.promise_control,\n        skipDownload:options.skipDownload,\n        commandOnAdvertise: () => commandSampleProfiler(options),\n        onSessionStart,","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/mono/browser/runtime/diagnostics/dotnet-cpu-profiler.ts#L1-L32","documentation":"Thrown by `collectCpuSamples` (dotnet-cpu-profiler) when no JS diagnostic session exists. Same precondition as the counters collector: the runtime must have advertised a session so the profiler can send its StartSampling command over the established transport.","triggerScenarios":"Calling `collectCpuSamples(options)` (dotnet-cpu-profiler.ts:11) before `serverSession` is set. Occurs when the profiler is invoked at startup, when the runtime has no diagnostics enabled, or before the advert handshake completes.","commonSituations":"Profiling before runtime ready; runtime published without the diagnostics module; misconfigured diagnostic ports.","solutions":["Defer `collectCpuSamples` until the runtime is ready and `serverSession` exists.","Publish the runtime with diagnostics enabled.","Confirm `DOTNET_DiagnosticPorts` is configured to expose the JS transport."],"exampleFix":"// before: called before session\nconst s = collectCpuSamples({}); // throws\n\n// after: wait for the diagnostic session\nawait waitForDiagSession();\nconst s = collectCpuSamples({ durationSeconds: 5 });","handlingStrategy":"validation","validationCode":"function canCollectCpuSamples () {\n  return !!serverSession;\n}\nif (canCollectCpuSamples()) collectCpuSamples({ durationSeconds: 5 });","typeGuard":"function hasActiveDiagSession (): boolean {\n  return typeof serverSession !== 'undefined' && serverSession !== null;\n}","tryCatchPattern":null,"preventionTips":["Defer profiling until the diagnostic session is established.","Enable diagnostics in the published runtime.","Surface the profiler UI only after the runtime is ready."],"tags":["diagnostics","cpu-profiler","session-management","startup"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}