{"record":{"id":"2c59cd9af0f0a8c1","repo":"dotnet/runtime","slug":"no-active-js-diagnostic-session","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-counters.ts","lineNumber":15,"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, commandCounters } from \"./client-commands\";\nimport { IDiagnosticSession } from \"./common\";\nimport { Module } from \"./globals\";\nimport { serverSession, setupJsClient } from \"./diagnostics-js\";\nimport { loaderHelpers } from \"./globals\";\n\nexport function collectMetrics (options?:DiagnosticCommandOptions):Promise<Uint8Array[]> {\n    if (!options) options = {};\n    if (!serverSession) {\n        throw new Error(\"No active JS diagnostic session\");\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    setupJsClient({\n        onClosePromise:onClosePromise.promise_control,\n        skipDownload:options.skipDownload,\n        commandOnAdvertise:() => commandCounters(options),\n        onSessionStart,\n    });\n    return onClosePromise.promise;\n}\n","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/mono/browser/runtime/diagnostics/dotnet-counters.ts#L1-L33","documentation":"Thrown by collectMetrics() (dotnet-counters) in diagnostics/dotnet-counters.ts when serverSession is undefined. collectMetrics drives a dotnet-counters trace by talking to the in-browser .NET diagnostic server via the JS IPC channel; it needs an established DiagnosticSession. Without serverSession there is no diagnostic server to send the StartTracing/counters command to.","triggerScenarios":"Calling API.collectMetrics() before the .NET diagnostic server has advertised (serverSession set in DiagnosticSession.send), or when diagnostics were not enabled for the runtime.","commonSituations":"Calling collectMetrics during early startup before the diagnostic server is up. A release build or configuration that did not start the diagnostic server (no diagnostic port configured).","solutions":["Wait for the runtime to be ready and the diagnostic server to advertise before calling collectMetrics.","Ensure diagnostics are enabled in the build/config (diagnostic port configured, js-module-diagnostics loaded).","Trigger a diagnostic session first (e.g. via the js://counters scenario URL or DOTNET_DiagnosticPorts) so serverSession exists."],"exampleFix":"null","handlingStrategy":"validation","validationCode":"import { serverSession } from \"./diagnostics-js\";\nasync function collectMetricsSafe(opts?: DiagnosticCommandOptions) {\n  if (!serverSession) {\n    throw new Error('No diagnostic session yet; ensure the runtime is ready and diagnostics enabled before calling collectMetrics.');\n  }\n  return collectMetrics(opts);\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Enable diagnostics in the build and trigger a session before collecting.","Call collectors only after the runtime is ready."],"tags":["diagnostics","dotnet-counters","session","ordering"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}