{"record":{"id":"937462ad5f95f0be","repo":"microsoft/aspire","slug":"dashboard-testing-is-not-supported-in-publish-mode","errorCode":null,"errorMessage":"Dashboard testing is not supported in publish mode.","messagePattern":"Dashboard testing is not supported in publish mode\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Testing/DistributedApplicationTestingBuilder.cs","lineNumber":360,"sourceCode":"            $\"{KnownConfigNames.DashboardFrontendBrowserToken}={browserToken}\",\n            $\"{KnownConfigNames.DashboardResourceServiceClientApiKey}={resourceServiceApiKey}\"\n        ];\n        applicationOptions.Args = hostBuilderOptions.Args;\n\n        hostBuilderOptions.Configuration ??= new();\n        AddDashboardTestingConfiguration(hostBuilderOptions.Configuration);\n    }\n\n    private static void ConfigureDashboardTesting(IDistributedApplicationBuilder builder, DashboardTestingState dashboardTestingState)\n    {\n        if (!dashboardTestingState.Enabled)\n        {\n            return;\n        }\n\n        if (builder.ExecutionContext.IsPublishMode)\n        {\n            throw new InvalidOperationException(Properties.Resources.DashboardTestingPublishModeExceptionMessage);\n        }\n\n        // Apply these after the builder has loaded environment variables and command-line arguments so test\n        // automation cannot accidentally opt back into fixed ports, anonymous access, or interactivity.\n        // Callers can still override runtime settings through the returned builder; constructor-time service\n        // selection, including dashboard authentication, has already completed.\n        AddDashboardTestingConfiguration(builder.Configuration);\n\n        // Restore the generated browser token if something cleared it. DistributedApplicationBuilder freezes the\n        // token into AppHost:BrowserToken during construction, but DashboardOptions does not read that key until the\n        // application starts, so AppHost code running between those two points can blank it. DashboardEventHandlers\n        // treats a null or empty token as a request for Unsecured frontend authentication, which would silently\n        // downgrade the authenticated default this opt-in promises, so the guard mirrors that same emptiness check\n        // and leaves any non-empty token, including a deliberately chosen one, alone. This runs after the AppHost\n        // entry point has finished configuring, because the builder is not handed back until it reaches Build(), and\n        // before the caller sees the builder, so a test that wants the anonymous dashboard can still choose it\n        // through the returned builder.\n        if (string.IsNullOrEmpty(builder.Configuration[\"AppHost:BrowserToken\"]))","sourceCodeStart":342,"sourceCodeEnd":378,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Testing/DistributedApplicationTestingBuilder.cs#L342-L378","documentation":"ConfigureDashboardTesting in DistributedApplicationTestingBuilder throws this InvalidOperationException when the test builder runs in publish mode (ExecutionContext.IsPublishMode). Dashboard testing configuration (fixed ports, anonymous access, interactivity suppression) only applies to run mode, so publish-mode execution is rejected rather than misconfigured.","triggerScenarios":"Creating a DistributedApplicationTestingBuilder whose execution context is publish mode — e.g. tests invoking the publishing pipeline or setting publish-mode environment flags before the dashboard testing configuration is applied.","commonSituations":"Reusing the testing builder for publish/deployment tests; environment variables (ASPIRE_*/DOTNET_* publish flags) leaking into test host config; mixing run-mode and publish-mode test setups.","solutions":["Run dashboard tests in run mode; do not enable publish mode in the test host configuration","Use the publish-mode APIs (e.g. builder.CreatePublishModeSnapshot / publishing tests) instead of the dashboard testing builder for deployment validation","Remove env/config that flips IsPublishMode (check for ASPNETCORE / ASPIRE publish switches in test setup)"],"exampleFix":"// before\nvar builder = await DistributedApplicationTestingBuilder.CreateAsync<Projects.AppHost>([], (o, _) => o.EnablePublishMode = true); // publish mode\n// after\nvar builder = await DistributedApplicationTestingBuilder.CreateAsync<Projects.AppHost>(); // run mode, dashboard testing allowed","handlingStrategy":"try-catch","validationCode":"var execContext = builder.ExecutionContext;\nif (execContext.IsPublishMode) { /* use publishing APIs instead of dashboard testing */ }","typeGuard":null,"tryCatchPattern":"try\n{\n    var builder = await DistributedApplicationTestingBuilder.CreateAsync<Projects.AppHost>();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"publish mode\"))\n{\n    // switch to publish-mode test APIs\n}","preventionTips":["Keep dashboard tests in run mode","Remove publish-mode env/config flags from the test host setup","Use dedicated publishing test APIs for deployment validation"],"tags":["aspire","testing","dashboard","publish-mode"],"backgroundTag":"unsupported-operation","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}