{"record":{"id":"271c66be15651b14","repo":"projectdiscovery/katana","slug":"could-not-get-forms","errorCode":null,"errorMessage":"could not get forms","messagePattern":"could not get forms","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/engine/headless/browser/element.go","lineNumber":66,"sourceCode":"// FindNavigation attempts to find more navigations on the page which could\n// be done to find more links and pages.\n//\n// This includes the following -\n//  1. Forms\n//  2. Buttons\n//  3. Links\n//  4. Elements with event listeners\n//\n// The navigations found are unique across the page. The caller\n// needs to ensure they are unique globally before doing further actions with details.\nfunc (b *BrowserPage) FindNavigations() ([]*types.Action, error) {\n\tunique := make(map[string]struct{})\n\n\tnavigations := make([]*types.Action, 0)\n\n\tforms, err := b.GetAllForms()\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"could not get forms\")\n\t}\n\tfor _, form := range forms {\n\t\tfor _, element := range form.Elements {\n\t\t\tif element.TagName != \"BUTTON\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// TODO: Check if this button is already in the unique map\n\t\t\t// and if so remove it\n\t\t\tunique[element.Hash()] = struct{}{}\n\t\t}\n\t\thash := form.Hash()\n\t\tif _, found := unique[hash]; found {\n\t\t\tcontinue\n\t\t}\n\t\tunique[hash] = struct{}{}\n\n\t\tnavigations = append(navigations, &types.Action{\n\t\t\tType: types.ActionTypeFillForm,","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/projectdiscovery/katana/blob/e3e742739c3746f085943ce918fb4e2b8daf6fe6/pkg/engine/headless/browser/element.go#L48-L84","documentation":"This error is a wrapper produced by BrowserPage.FindNavigations (katana headless engine) when b.GetAllForms() fails. GetAllForms evaluates `window.getAllForms()` in the page context via the Chrome DevTools Protocol; failure means the CDP eval itself errored or the returned JSON could not be unmarshaled into []*types.HTMLForm. It aborts the navigation-discovery step, so no actions (forms/buttons/links) are returned for the page.","triggerScenarios":"1) The page/tab was closed or crashed so the CDP eval fails. 2) Navigation destroyed the execution context mid-crawl (the page changed while FindNavigations ran). 3) The injected window.getAllForms helper is missing because page scripts/init scripts were not installed on the new document. 4) The eval result could not be JSON-unmarshaled into HTMLForm structs (unexpected shape).","commonSituations":"Crawling SPAs that replace the document frequently; crawling a page that redirects or closes tabs; browser resource exhaustion (renderer crash) under heavy concurrency; custom hook code removing injected helpers.","solutions":["Retry FindNavigations once after the page has fully loaded; transient CDP context errors often resolve after a re-load","Check that the target URL is reachable and does not crash the tab (test manually in Chrome)","Reduce concurrency/headless resource usage and re-run","Update katana; newer builds harden eval/unmarshal failures"],"exampleFix":"// before\nnavigations, err := page.FindNavigations()\nif err != nil { return err }\n// after\nnavigations, err := page.FindNavigations()\nif err != nil {\n    logger.Debug(\"navigation discovery failed, skipping page\", slog.String(\"error\", err.Error()))\n    return nil // degrade gracefully instead of failing the crawl\n}","handlingStrategy":"fallback","validationCode":"// ensure the page is live and loaded before discovery\nif page == nil || page.Closed() { return nil }\nif err := page.WaitPageLoadHeurisitics(); err != nil { return nil }","typeGuard":"func pageUsable(p *browser.BrowserPage) bool { return p != nil && !p.Closed() }","tryCatchPattern":"navs, err := page.FindNavigations()\nif err != nil {\n    if _, isCtx := errors.Cause(err).(*cdp.ExecutionContextDestroyedError); isCtx {\n        return retryOnce(page) // transient\n    }\n    return nil // skip page\n}","preventionTips":["Wait for load completion before DOM discovery","Retry transient CDP eval errors once","Keep browser memory sane to avoid renderer crashes","Skip (don't fail) the crawl on per-page discovery errors"],"tags":["headless-browser","cdp-eval","crawl"],"backgroundTag":"cdp-evaluation-failed","analyzedSha":"e3e742739c3746f085943ce918fb4e2b8daf6fe6","analyzedAt":"2026-09-03T14:55:13.248Z","contentChangedAt":"2026-09-03T14:55:13.248Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}