{"record":{"id":"12541cac9398805a","repo":"PuerkitoBio/goquery","slug":"invalid-sibling-type","errorCode":null,"errorMessage":"Invalid sibling type.","messagePattern":"Invalid sibling type\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"traversal.go","lineNumber":647,"sourceCode":"\t\t\t\t\t\tret = skipNode.NextSibling\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase siblingPrev, siblingPrevAll, siblingPrevUntil:\n\t\t\t\tif cur == nil {\n\t\t\t\t\t// Start with previous sibling of the skip node\n\t\t\t\t\tret = skipNode.PrevSibling\n\t\t\t\t} else {\n\t\t\t\t\tret = cur.PrevSibling\n\t\t\t\t}\n\t\t\tcase siblingNext, siblingNextAll, siblingNextUntil:\n\t\t\t\tif cur == nil {\n\t\t\t\t\t// Start with next sibling of the skip node\n\t\t\t\t\tret = skipNode.NextSibling\n\t\t\t\t} else {\n\t\t\t\t\tret = cur.NextSibling\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tpanic(\"Invalid sibling type.\")\n\t\t\t}\n\t\t\tif ret == nil || ret.Type == html.ElementNode || st == siblingAllIncludingNonElements {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// Not a valid node, try again from this one\n\t\t\tcur = ret\n\t\t}\n\t}\n\n\t// For the cases that collect every matching sibling, count them in a\n\t// cheap pointer walk first so the result slice can be sized exactly,\n\t// avoiding repeated slice growth. The Until cases are skipped (counting\n\t// would require running the predicate twice) and so are the single-result\n\t// Next/Prev cases.\n\tswitch st {\n\tcase siblingAll, siblingAllIncludingNonElements, siblingPrevAll, siblingNextAll:\n\t\tn := 0\n\t\tfor c := iter(nil); c != nil; c = iter(c) {","sourceCodeStart":629,"sourceCodeEnd":665,"githubUrl":"https://github.com/PuerkitoBio/goquery/blob/738783cbc3c6244dea65b66306dae4fd0f84e7e3/traversal.go#L629-L665","documentation":"This panic is thrown inside goquery's internal sibling iterator (getChildrenWithSiblingType in traversal.go) when the siblingType enum value st does not match any known case (siblingAll, siblingPrev*, siblingNext*, etc.). It is an internal invariant violation: there is no public API that legitimately produces an unknown siblingType, so hitting it means internal state is corrupted or the library was modified.","triggerScenarios":"Not reachable through correct public API usage. Traversal calls Next*, Prev*, Siblings*, Parents*, Children* (Until/WithNodes variants) all pass valid constants; the panic fires only if a fork or patch introduces a new siblingType without adding a switch case.","commonSituations":"Developers patching or forking goquery's traversal.go; custom builds where a new sibling type constant is defined but not handled in the iterator's switch; corrupted binary from a bad build.","solutions":["Use the official goquery release; rebuild from a clean checkout of the module.","If you forked the code, add the missing case to the switch in getChildrenWithSiblingType (traversal.go) for any new siblingType constant.","Capture the stack trace and report it upstream with the exact call chain."],"exampleFix":"// before (fork adds a new type but no case)\nconst siblingFiltered siblingType = 99\n\n// after (handle it in getChildrenWithSiblingType)\ncase siblingFiltered:\n\tif cur == nil {\n\t\tret = skipNode.NextSibling\n\t} else {\n\t\tret = cur.NextSibling\n\t}\n\tif ret != nil && ret.Type != html.ElementNode {\n\t\tret = nil // apply filter semantics\n\t}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"defer func() {\n\tif r := recover(); r != nil {\n\t\tif errStr, ok := r.(string); ok && errStr == \"Invalid sibling type.\" {\n\t\t\terr = fmt.Errorf(\"goquery internal error: %v\", r)\n\t\t\treturn\n\t\t}\n\t\tpanic(r)\n\t}\n}()","preventionTips":["Do not fork or patch goquery's traversal internals; if you must, extend the siblingType switch completely.","Pin and verify module checksums (go.sum) so a tampered build cannot introduce invalid enum values.","Wrap bulk scraping operations in a recover boundary so one internal panic does not kill a long-running crawler."],"tags":["go","goquery","traversal","panic"],"backgroundTag":"internal-invariant-violation","analyzedSha":"738783cbc3c6244dea65b66306dae4fd0f84e7e3","analyzedAt":"2026-09-06T07:49:12.071Z","contentChangedAt":"2026-09-06T07:49:12.071Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}