microsoft/aspire · error · InvalidOperationException

BrowserMessageStrings.BrowserLogsTrackedBrowserProfileConfli…

Error message

BrowserMessageStrings.BrowserLogsTrackedBrowserProfileConflict

What it means

BrowserEndpointDiscovery.TryReadAndValidateAsync reads sidecar metadata tracking a live Aspire-launched browser for a given user-data root. If the tracked browser exists for the same user-data root but its profile directory name differs from the requested profile, this is treated as a genuine conflict (not stale metadata) and throws with BrowserLogsTrackedBrowserProfileConflict, reporting the user-data root, the tracked profile name, and the requested profile name.

Solutions

  1. Close the currently running tracked browser (or kill its process) so discovery can launch a fresh one with the requested profile.
  2. Make the profile name in your WithBrowserLogs configuration match the profile of the running browser.
  3. Clear stale sidecar metadata after killing the browser and retry.
  4. Avoid sharing one user-data root across app hosts configured with different profiles.

Example fix

// before
.WithBrowserLogs(new Dictionary<string, string?> { ["profile"] = "newprofile" }) // old browser running with 'oldprofile'

// after: stop the old browser first, or keep profile consistent
# taskkill /IM chrome.exe /F  (or close the tracked browser window)
.WithBrowserLogs(new Dictionary<string, string?> { ["profile"] = "oldprofile" })
Defensive patterns

Strategy: retry

Validate before calling

// Before requesting browser logs, ensure no tracked browser with a different profile is running for the same user-data root
// (close prior browser instances or match the configured profile to the running one).

Try / catch

try { await discovery.TryReadAndValidateAsync(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("profile conflict"))
{ logger.LogWarning(ex, "Killing tracked browser with mismatched profile and retrying"); /* kill browser, clear metadata, retry once */ }

Prevention

When it happens

Trigger: Requesting browser-logs capture with profile P while an already-running Aspire-launched browser for the same user-data root was started with profile Q; calling TryReadAndValidateAsync again after switching the profile configuration without restarting the tracked browser.

Common situations: Changing the profile name in WithBrowserLogs between app-host runs while an old browser instance is still open; two app-host sessions sharing a user-data root but configured with different profiles; a leftover browser process from a crashed session holding the user-data root.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/949b8484699e960c. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Browsers/BrowserEndpointDiscovery.cs:139

        }
        catch (Exception ex) when (!cancellationToken.IsCancellationRequested && ex is HttpRequestException or IOException or JsonException or OperationCanceledException)
        {
            _logger.LogDebug(ex, "Tracked browser endpoint metadata '{MetadataPath}' points to endpoint '{Endpoint}', but probing /json/version failed.", metadataPath, endpoint);
            endpointResponded = false;
        }

        if (!endpointResponded)
        {
            _logger.LogDebug("Tracked browser endpoint metadata '{MetadataPath}' points to endpoint '{Endpoint}', but it did not respond to /json/version.", metadataPath, endpoint);
            TryDelete(metadataPath);
            return null;
        }

        // At this point the sidecar points at a live Aspire-launched browser for the same user-data root. A profile
        // mismatch is therefore a real conflict, not stale metadata, and should be reported to the caller.
        if (!string.Equals(metadata.ProfileDirectoryName, profileDirectoryName, StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException(
                string.Format(
                    CultureInfo.CurrentCulture,
                    BrowserMessageStrings.BrowserLogsTrackedBrowserProfileConflict,
                    identity.UserDataRootPath,
                    metadata.ProfileDirectoryName ?? BrowserMessageStrings.BrowserLogsDefaultProfileName,
                    profileDirectoryName ?? BrowserMessageStrings.BrowserLogsDefaultProfileName));
        }

        return metadata with { Endpoint = endpoint.ToString() };
    }

    public static async Task WriteAsync(BrowserHostIdentity identity, string? profileDirectoryName, Uri endpoint, int processId, CancellationToken cancellationToken)
    {
        var metadataPath = GetEndpointMetadataFilePath(identity.UserDataRootPath);
        var tempPath = $"{metadataPath}.{Guid.NewGuid():N}.tmp";
        // The sidecar captures the identity that was used to launch the owned browser, not just the endpoint URL. That
        // lets a future AppHost reject metadata from a different browser executable or user-data root before connecting.
        //

View on GitHub (pinned to 25830f84bd)