{"record":{"id":"b6593a0624e0357f","repo":"projectdiscovery/nuclei","slug":"element-did-not-appear-in-the-given-amount-of-time","errorCode":null,"errorMessage":"Element did not appear in the given amount of time","messagePattern":"Element did not appear in the given amount of time","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/protocols/headless/engine/page_actions.go","lineNumber":225,"sourceCode":"\t}\n\n\tpollTime, err := getTimeParameter(p, act, \"pollTime\", 100, time.Millisecond)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Wrong polling time given\")\n\t}\n\n\tlookupPage := p.Sleeper(pollTime, timeout).Timeout(timeout)\n\telement, _, err := p.pageElementBy(lookupPage.Page(), act)\n\tif err != nil {\n\t\treturn errors.Wrap(err, errElementDidNotAppear)\n\t}\n\n\tif element != nil {\n\t\tif err := element.WaitVisible(); err != nil {\n\t\t\treturn errors.Wrap(err, errElementDidNotAppear)\n\t\t}\n\t} else {\n\t\treturn errors.New(errElementDidNotAppear)\n\t}\n\n\treturn nil\n}\n\nfunc (p *Page) Sleeper(pollTimeout, timeout time.Duration) *Page {\n\tpage := *p\n\tpage.page = page.Page().Sleeper(func() utils.Sleeper {\n\t\treturn createBackOffSleeper(pollTimeout, timeout)\n\t})\n\treturn &page\n}\n\nfunc (p *Page) Timeout(timeout time.Duration) *Page {\n\tpage := *p\n\tpage.page = page.Page().Timeout(timeout)\n\treturn &page\n}","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/projectdiscovery/nuclei/blob/265b3a3dec374741614e342f813c10f8b38d2bb7/pkg/protocols/headless/engine/page_actions.go#L207-L243","documentation":"Produced by the waitfor action path: the page is polled with a backoff sleeper (pollTime up to timeout) via pageElementBy; if that lookup errors, or the element is found but never becomes visible (element.WaitVisible), the underlying error is wrapped with 'Element did not appear in the given amount of time'. A nil lookup result returns the bare error.","triggerScenarios":"A `action: waitfor` step with a selector/XPath that never matches before the timeout elapses; SPA content that renders later than page-timeout; anti-bot pages that replace the DOM before the element becomes visible.","commonSituations":"Selectors copied from a page whose markup has since changed; timeouts left at default while the target app is slow; element behind a login/interaction so it never appears on the initial page.","solutions":["Verify the selector matches in browser DevTools on the actual rendered page","Raise the wait budget: `timeout` arg on the action and/or -page-timeout globally","Precede waitfor with waitload/waitidle so the DOM settles before polling starts","Loosen the selector (partial attribute match, XPath contains()) to survive markup drift"],"exampleFix":"# before\n- action: waitfor\n  selector: '#dashboard-user-profile-9281'\n\n# after\n- action: waitload\n- action: waitfor\n  selector: '[id*=\"user-profile\"]'\n  timeout: 15000","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := page.WaitDOMContentLoaded() // no; concrete pattern:\nif err := instance.Run(...); err != nil {\n    if strings.Contains(err.Error(), errElementDidNotAppear) {\n        // selector/timeout problem: log target for manual review, do not abort the whole scan\n        gologger.Warning().Msgf(\"element not found on %s\", target)\n        continue\n    }\n    return err\n}","preventionTips":["Test selectors against the live rendered DOM in DevTools before templating","Give waitfor steps explicit generous `timeout` args on slow apps","Stabilize pages with waitload/waitidle before waiting on specific elements"],"tags":["headless","dom","selector","timeout","waitfor"],"backgroundTag":null,"analyzedSha":"265b3a3dec374741614e342f813c10f8b38d2bb7","analyzedAt":"2026-08-15T20:05:51.855Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}