{"record":{"id":"6a43625170e81b89","repo":"microsoft/aspire","slug":"cannot-resolve-the-isolated-browser-user-data-directory","errorCode":null,"errorMessage":"Cannot resolve the isolated browser user data directory because the AppHost path identifier is not available. Use '{0}' user data mode or run from a configured AppHost.","messagePattern":"Cannot resolve the isolated browser user data directory because the AppHost path identifier is not available\\. Use '(.+?)' user data mode or run from a configured AppHost\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Browsers/BrowserUserDataPathResolver.cs","lineNumber":105,"sourceCode":"                \"Application Support\",\n                \"Aspire\",\n                \"BrowserData\");\n        }\n\n        // XDG: prefer XDG_DATA_HOME, fall back to ~/.local/share. Lower-case segment names match the\n        // conventional XDG layout (e.g. ~/.config/google-chrome).\n        var xdgDataHome = Environment.GetEnvironmentVariable(\"XDG_DATA_HOME\");\n        var dataHome = !string.IsNullOrEmpty(xdgDataHome)\n            ? xdgDataHome\n            : Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), \".local\", \"share\");\n        return Path.Combine(dataHome, \"aspire\", \"browser-data\");\n    }\n\n    private static string GetAppHostSegment(BrowserConfiguration configuration)\n    {\n        if (string.IsNullOrWhiteSpace(configuration.AppHostKey))\n        {\n            throw new InvalidOperationException(\n                string.Format(\n                    CultureInfo.CurrentCulture,\n                    BrowserMessageStrings.BrowserLogsAppHostPathShaNotAvailable,\n                    BrowserUserDataMode.Isolated));\n        }\n\n        return configuration.AppHostKey.Length > AppHostShaSegmentLength\n            ? configuration.AppHostKey[..AppHostShaSegmentLength]\n            : configuration.AppHostKey;\n    }\n\n    // Maps a logical browser name or executable path to a stable lower-case folder segment so a Chrome -> Edge\n    // configuration flip never silently shares state with the previous browser. Unknown executables fall back to\n    // a sanitized form of the file name without extension.\n    private static string NormalizeBrowserSegment(string browser)\n    {\n        var name = Path.IsPathRooted(browser) || Path.IsPathFullyQualified(browser)\n            ? Path.GetFileNameWithoutExtension(browser)","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Browsers/BrowserUserDataPathResolver.cs#L87-L123","documentation":"BrowserUserDataPathResolver.GetAppHostSegment throws this when BrowserConfiguration.AppHostKey is null/whitespace while resolving an 'Isolated' user-data directory. The isolated path layout embeds a hash/segment derived from the AppHost identity, so without an AppHostKey the resolver cannot construct a unique per-AppHost directory and refuses to guess a shared location.","triggerScenarios":"Using BrowserUserDataMode.Isolated (the message interpolates the Isolated mode name) while the BrowserConfiguration was built without setting AppHostKey — e.g., running outside a configured AppHost context.","commonSituations":"Launching a tracked browser from a standalone tool or test host that has no AppHost; constructing BrowserConfiguration manually and forgetting AppHostKey; switching user data mode to Isolated without migrating configuration.","solutions":["Set configuration.AppHostKey to the AppHost's identifier before resolving the user data path.","Use BrowserUserDataMode with a non-isolated mode (per the message) that does not require the AppHost segment.","Run the browser launch from a properly configured AppHost so the key is populated automatically.","Fall back to a non-isolated data directory when AppHostKey is unavailable."],"exampleFix":"// before\nvar config = new BrowserConfiguration { UserDataMode = BrowserUserDataMode.Isolated };\nvar path = BrowserUserDataPathResolver.Resolve(config);\n// after\nvar config = new BrowserConfiguration { UserDataMode = BrowserUserDataMode.Isolated, AppHostKey = appHostIdentifier };\nvar path = BrowserUserDataPathResolver.Resolve(config);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrWhiteSpace(config.AppHostKey) && config.UserDataMode == BrowserUserDataMode.Isolated)\n{\n    config = config with { UserDataMode = BrowserUserDataMode.Default };\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    var path = BrowserUserDataPathResolver.Resolve(config);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"user data directory\"))\n{\n    config = config with { UserDataMode = BrowserUserDataMode.Default };\n    var path = BrowserUserDataPathResolver.Resolve(config);\n}","preventionTips":["Always populate AppHostKey when constructing BrowserConfiguration in non-AppHost contexts.","Pick the user data mode once, based on whether an AppHost identity is available.","Add a startup assertion that required configuration fields are set."],"tags":["browser","configuration","user-data","apphost"],"backgroundTag":"missing-required-config-field","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"}