{"record":{"id":"df50eb87cb69ec17","repo":"CloakHQ/CloakBrowser","slug":"elementnotattachederror-selector","errorCode":null,"errorMessage":"ElementNotAttachedError: {selector}","messagePattern":"ElementNotAttachedError: (.+?)","errorType":"exception","errorClass":"ElementNotAttachedError","httpStatus":null,"severity":"error","filePath":"dotnet/src/CloakBrowser/Wrappers/LocatorHumanizer.cs","lineNumber":20,"sourceCode":"using 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);\n    }\n\n    private static async Task<BoundingBox?> GetBoxAsync(\n        IsolatedWorld world, string selector, double timeoutMs)\n    {\n        double deadline = System.Environment.TickCount64 + System.Math.Max(0, timeoutMs);\n        var result = await StealthDom.BoxAsync(world, selector).ConfigureAwait(false);\n        while ((result.Status == StealthStatus.NotFound || result.Status == StealthStatus.EvaluationFailed)","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/dotnet/src/CloakBrowser/Wrappers/LocatorHumanizer.cs#L2-L38","documentation":"ElementNotAttachedError mapped from StealthStatus.NotFound in LocatorHumanizer.SnapshotAsync: the stealth DOM snapshot for the selector found no matching element, so the humanized locator action (check, uncheck, click, focus...) aborts.","triggerScenarios":"Humanized Check/Uncheck/move on a selector with no attached match within the snapshot — element not yet rendered, wrong selector, or element removed before the call.","commonSituations":"SPA late rendering, selector typos, elements behind auth/redirects so the page content differs from expectation, virtualized lists.","solutions":["Wait for the element to be attached/visible before the humanized action (locator.WaitForAsync)","Verify the selector matches (count == 1) with a debug query","Handle auth/redirects so the expected page is actually loaded","Retry after content settles in dynamic SPAs"],"exampleFix":"// before\nawait page.Locator(\"#agree\").HumanCheckAsync();\n\n// after\nawait page.Locator(\"#agree\").WaitForAsync(new() { State = WaitForSelectorState.Visible });\nawait page.Locator(\"#agree\").HumanCheckAsync();","handlingStrategy":"try-catch","validationCode":"await page.Locator(selector).WaitForAsync(new() { State = WaitForSelectorState.Attached });","typeGuard":null,"tryCatchPattern":"catch (ElementNotAttachedError) { await page.WaitForSelectorAsync(selector); retry once; }","preventionTips":["Wait for the element before humanized locator actions","Verify selectors match after auth flows","Use stable data-testid attributes"],"tags":["humanize","locator","element-not-found","stealth"],"backgroundTag":"element-not-found","analyzedSha":"d6bad5de261bedf025280ace1d14e800aee13923","analyzedAt":"2026-08-28T14:13:12.918Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}