{"record":{"id":"4434da94f1ea2ec8","repo":"microsoft/aspire","slug":"dashboardclient-is-disabled-check-the-isenabled-property","errorCode":null,"errorMessage":"DashboardClient is disabled. Check the IsEnabled property before calling this.","messagePattern":"DashboardClient is disabled\\. Check the IsEnabled property before calling this\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Aspire.Dashboard/ServiceClient/DashboardClient.cs","lineNumber":328,"sourceCode":"                if (_initialDataReceivedTcs.Task.IsCompleted)\n                {\n                    _initialDataReceivedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);\n                }\n            }\n        }\n\n        // Invoke the event outside the lock to avoid potential deadlocks\n        // if a subscriber tries to access DashboardClient state.\n        ConnectionStateChanged?.Invoke(state);\n    }\n\n    private void EnsureInitialized()\n    {\n        var priorState = Interlocked.CompareExchange(ref _state, value: StateInitialized, comparand: StateNone);\n\n        if (priorState is StateDisabled)\n        {\n            throw new InvalidOperationException($\"{nameof(DashboardClient)} is disabled. Check the {nameof(IsEnabled)} property before calling this.\");\n        }\n\n        if (priorState is not StateNone)\n        {\n            ObjectDisposedException.ThrowIf(priorState is StateDisposed, this);\n            return;\n        }\n\n        SetConnectionState(DashboardConnectionState.Connecting);\n        // The connection watches resources for the lifetime of the dashboard. Don't let the request or\n        // component that first accesses the client become the parent of that long-running operation.\n        using (ExecutionContext.SuppressFlow())\n        {\n            _connection = Task.Run(() => ConnectAndWatchAsync(_clientCancellationToken), _clientCancellationToken);\n        }\n    }\n\n    async Task ConnectAndWatchAsync(CancellationToken cancellationToken)","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Dashboard/ServiceClient/DashboardClient.cs#L310-L346","documentation":"EnsureInitialized enforces a state machine on DashboardClient. If the client was created with the feature disabled (StateDisabled), any call that requires initialization throws InvalidOperationException telling the caller to check the IsEnabled property first.","triggerScenarios":"Calling StartAsync/GetResources/etc. on a DashboardClient constructed while the dashboard resource-service client was disabled — i.e. IsEnabled was false but client methods were invoked anyway.","commonSituations":"Consumer code (e.g. structured logs/metrics/traces pages) not checking DashboardClient.IsEnabled when the resource service client is intentionally disabled by configuration; using the client in unit tests with default options where the client is disabled.","solutions":["Check client.IsEnabled before calling any DashboardClient methods and skip/disable the dependent feature when false.","Enable the resource service client in configuration so the client initializes (provide valid auth endpoints/certs).","If hosting the dashboard yourself, register/configure the DashboardClient (AddDashboardClient) instead of relying on a disabled instance.","Subscribe to the client's state/initialization events rather than assuming it is usable."],"exampleFix":"// before\nawait dashboardClient.StartAsync(cancellationToken);\nawait dashboardClient.GetResourcesAsync(cancellationToken);\n// after\nif (dashboardClient.IsEnabled)\n{\n    await dashboardClient.StartAsync(cancellationToken);\n    await dashboardClient.GetResourcesAsync(cancellationToken);\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"if (!dashboardClient.IsEnabled)\n{\n    logger.LogWarning(\"DashboardClient disabled; skipping resource watch.\");\n    return;\n}","tryCatchPattern":"try { await dashboardClient.StartAsync(ct); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"is disabled\"))\n{\n    logger.LogWarning(\"DashboardClient is disabled; feature unavailable.\");\n}","preventionTips":["Always gate DashboardClient usage behind an IsEnabled check.","Enable the resource service client in configuration if the feature is needed.","Cover both enabled and disabled config paths in feature tests."],"tags":["state","initialization","configuration"],"backgroundTag":"feature-not-enabled","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}