CloakHQ/CloakBrowser · error · ElementNotAttachedError
ElementNotAttachedError: {sourceSelector}
Error message
ElementNotAttachedError: {sourceSelector} What it means
Thrown by the humanized drag-and-drop flow in HumanPage when the SOURCE element's bounding box cannot be resolved within the timeout. It means GetBoxAsync returned null for the source selector, so the drag cannot compute a start point.
Source
Thrown at dotnet/src/CloakBrowser/Human/HumanPage.cs:636
return scroll.DidScroll;
}
// -----------------------------------------------------------------------
// Drag-and-drop (humanized: move to source center, down, move to target, up)
// -----------------------------------------------------------------------
/// <summary>Human-like drag from <paramref name="sourceSelector"/> to
/// <paramref name="targetSelector"/>. Port of <c>_frame_drag_and_drop</c> / <c>_humanized_drag_to</c>:
/// moves to the source center, presses, moves to the target center, releases.</summary>
public async Task DragAndDropAsync(string sourceSelector, string targetSelector, HumanActionOptions? options = null)
{
await EnsureCursorInitAsync().ConfigureAwait(false);
double timeout = options?.Timeout ?? 30000;
var srcBox = await GetBoxAsync(sourceSelector, timeout).ConfigureAwait(false);
var tgtBox = await GetBoxAsync(targetSelector, timeout).ConfigureAwait(false);
if (srcBox == null)
throw new ElementNotAttachedError(sourceSelector);
if (tgtBox == null)
throw new ElementNotAttachedError(targetSelector);
BoundingBox src = srcBox.Value;
BoundingBox tgt = tgtBox.Value;
double sx = src.X + src.Width / 2;
double sy = src.Y + src.Height / 2;
double tx = tgt.X + tgt.Width / 2;
double ty = tgt.Y + tgt.Height / 2;
await HumanMouse.HumanMoveAsync(_rawMouse, _cursor.X, _cursor.Y, sx, sy, _cfg).ConfigureAwait(false);
_cursor.X = sx; _cursor.Y = sy;
await HumanRandom.SleepMsAsync(HumanRandom.Rand(100, 200)).ConfigureAwait(false);
await _rawMouse.DownAsync().ConfigureAwait(false);
await HumanRandom.SleepMsAsync(HumanRandom.Rand(80, 150)).ConfigureAwait(false);
await HumanMouse.HumanMoveAsync(_rawMouse, _cursor.X, _cursor.Y, tx, ty, _cfg).ConfigureAwait(false);
_cursor.X = tx; _cursor.Y = ty;
await HumanRandom.SleepMsAsync(HumanRandom.Rand(80, 150)).ConfigureAwait(false);View on GitHub (pinned to d6bad5de26)
Solutions
- Verify the source selector matches exactly one attached element (test with page.QuerySelectorAsync first or a Playwright locator)
- Wait for the element to be visible before dragging (page.WaitForSelectorAsync with state Visible)
- Increase options.Timeout
- If the element is in a frame/shadow DOM, use a selector scoped to that context
Example fix
// before
await page.DragAsync("#src", "#dst");
// after
await page.WaitForSelectorAsync("#src", new() { State = WaitForSelectorState.Visible });
await page.DragAsync("#src", "#dst", new DragOptions { Timeout = 60000 }); Defensive patterns
Strategy: validation
Validate before calling
var el = await page.QuerySelectorAsync(sourceSelector);
if (el == null) throw new InvalidOperationException($"source missing: {sourceSelector}"); Try / catch
catch (ElementNotAttachedError e) when (e.Message.Contains(sourceSelector)) { /* re-wait and retry once */ } Prevention
- Wait for source element visibility before drag calls
- Prefer stable data-testid selectors
- Pass an explicit generous Timeout in drag options
When it happens
Trigger: Calling HumanPage drag APIs (e.g. DragAsync(sourceSelector, targetSelector, options)) where the source selector matches no attached element within options.Timeout (default 30000 ms), or the element is detached/hidden when the box is queried.
Common situations: Selector typo, element rendered late (SPA), element inside an iframe or shadow root the selector doesn't reach, or a too-short options.Timeout passed by the caller.
Related errors
- ElementNotAttachedError: {targetSelector}
- Element not found while scrolling into view
- Humanized selector ${selector} is not supported by the isola
- Humanized selector ${selector} is not supported by the isola
- Humanized DOM read requires an active isolated world
AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28).
Data as JSON: /api/errors/09f165ab8e5f9344.
Report an issue: GitHub.