{"record":{"id":"4cbc90cb84c171cf","repo":"CloakHQ/CloakBrowser","slug":"stealthworldunavailableerror-4cbc90","errorCode":null,"errorMessage":"StealthWorldUnavailableError","messagePattern":"StealthWorldUnavailableError","errorType":"exception","errorClass":"StealthWorldUnavailableError","httpStatus":null,"severity":"critical","filePath":"dotnet/src/CloakBrowser/Wrappers/LocatorHumanizer.cs","lineNumber":12,"sourceCode":"using CloakBrowser.Human;\nusing Microsoft.Playwright;\n\nnamespace CloakBrowser.Wrappers;\n\n/// <summary>Humanized locator actions. Direct page.Locator selectors use the canonical isolated DOM world; unknown locator shapes retain the legacy Playwright path.</summary>\ninternal static class LocatorHumanizer\n{\n    private static double RemainingMs(double deadline) => Actionability.RemainingMs(deadline);\n\n    private static async Task<IsolatedWorld> WorldAsync(HumanCursor cursor) =>\n        await cursor.GetStealthAsync().ConfigureAwait(false) ?? throw new StealthWorldUnavailableError();\n\n    internal static async Task<StealthSnapshot> SnapshotAsync(HumanCursor cursor, string selector)\n    {\n        var (status, snapshot) = await StealthDom.SnapshotAsync(await WorldAsync(cursor).ConfigureAwait(false), selector).ConfigureAwait(false);\n        return status switch\n        {\n            StealthStatus.Ok when snapshot != null => snapshot.Value,\n            StealthStatus.NotFound => throw new ElementNotAttachedError(selector),\n            StealthStatus.Unsupported => throw new UnsupportedHumanizeSelectorError(selector),\n            _ => throw new StealthEvaluationError(selector),\n        };\n    }\n\n    internal static async Task EnsureActionableAsync(HumanCursor cursor, string selector,\n        IReadOnlySet<string> checks, double timeout, bool force)\n    {\n        var world = await WorldAsync(cursor).ConfigureAwait(false);\n        await Actionability.EnsureActionableAsync(cursor.Page, selector, checks, timeout, force, world).ConfigureAwait(false);","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/dotnet/src/CloakBrowser/Wrappers/LocatorHumanizer.cs#L1-L30","documentation":"StealthWorldUnavailableError thrown by LocatorHumanizer.WorldAsync when cursor.GetStealthAsync() returns null — the locator humanizer needs the stealth isolated world to run its DOM scripts, and it isn't present on this page/context.","triggerScenarios":"Calling humanized locator actions (Check/Uncheck/Click via humanize wrappers) on a page whose context was created without stealth scripts, or after the world has been torn down (page closing).","commonSituations":"Creating a BrowserContext manually instead of via CloakBrowser's launch APIs, disabling stealth features programmatically, or racing page teardown.","solutions":["Create contexts/pages through CloakBrowser's launch/launch_context helpers so the stealth world is installed","Don't disable the stealth/isolated-world feature for pages you humanize","Guard calls with a page-open check and stop humanizing during teardown"],"exampleFix":"# before\ncontext = await browser.new_context()  # no stealth world\n\n# after\ncontext = await cloakbrowser.launch_context(...)  # installs stealth world","handlingStrategy":"validation","validationCode":"var world = await cursor.GetStealthAsync();\nif (world == null) throw new InvalidOperationException(\"create context via cloakbrowser launch APIs\");","typeGuard":null,"tryCatchPattern":"catch (StealthWorldUnavailableError) { recreate context through launch_context; }","preventionTips":["Always create contexts via CloakBrowser launch APIs","Don't disable stealth for pages you humanize","Stop humanizing once page teardown begins"],"tags":["stealth","isolated-world","configuration","locator"],"backgroundTag":"missing-browser-context-setup","analyzedSha":"d6bad5de261bedf025280ace1d14e800aee13923","analyzedAt":"2026-08-28T14:13:12.918Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}