{"record":{"id":"0226960ca500e98f","repo":"dgtlmoon/changedetection.io","slug":"non200errorcodereceived","errorCode":null,"errorMessage":"Non200ErrorCodeReceived","messagePattern":"Non200ErrorCodeReceived","errorType":"exception","errorClass":"Non200ErrorCodeReceived","httpStatus":null,"severity":"error","filePath":"changedetectionio/content_fetchers/playwright.py","lineNumber":359,"sourceCode":"            except Exception as e:\n                # https://github.com/dgtlmoon/changedetection.io/discussions/2122#discussioncomment-8241962\n                logger.critical(f\"Response from the browser/Playwright did not have a status_code! Response follows.\")\n                logger.critical(response)\n                await context.close()\n                await browser.close()\n                raise PageUnloadable(url=url, status_code=None, message=str(e))\n\n            if fetch_favicon:\n                try:\n                    self.favicon_blob = await self.page.evaluate(FAVICON_FETCHER_JS)\n                    await self.page.request_gc()\n                except Exception as e:\n                    logger.error(f\"Error fetching FavIcon info {str(e)}, continuing.\")\n\n            if self.status_code != 200 and not ignore_status_codes:\n                screenshot = await capture_full_page_async(self.page, screenshot_format=self.screenshot_format, watch_uuid=watch_uuid, lock_viewport_elements=self.lock_viewport_elements)\n                # Finally block will handle cleanup\n                raise Non200ErrorCodeReceived(url=url, status_code=self.status_code, screenshot=screenshot)\n\n            if not empty_pages_are_a_change and len((await self.page.content()).strip()) == 0:\n                logger.debug(\"Content Fetcher > Content was empty, empty_pages_are_a_change = False\")\n                await context.close()\n                await browser.close()\n                raise EmptyReply(url=url, status_code=response.status)\n\n            # Wrap remaining operations in try/finally to ensure cleanup\n            try:\n                # Run Browser Steps here\n                if self.browser_steps:\n                    try:\n                        await self.iterate_browser_steps(start_url=url)\n                    except BrowserStepsStepException:\n                        # Finally block will handle cleanup\n                        raise\n\n                    await self.page.wait_for_timeout(extra_wait * 1000)","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/dgtlmoon/changedetection.io/blob/5d9c7c6da76340597243e8163c4f2439237fa0e8/changedetectionio/content_fetchers/playwright.py#L341-L377","documentation":"After the jq import succeeds, the input is checked with validate_jq_expression() and compiled with jq.compile(). If either raises ValueError, the validator reports the expression as invalid jq, embedding jq's compiler error message.","triggerScenarios":"Submitting 'jq:' lines with syntax errors such as 'jq:.foo bar', unbalanced braces 'jq:{a:', or a guard-rules violation flagged by validate_jq_expression (e.g. disallowed constructs) — anything that makes jq.compile raise ValueError.","commonSituations":"Typos in jq filter programs; using jq CLI-only syntax not supported by the python binding's version; overly long programs caught by the built-in safety validation (validate_jq_expression enforces length/complexity limits).","solutions":["Test the filter with the jq CLI or `python -c \"import jq; jq.compile('...')\"`","Simplify the filter; check braces/quotes are balanced","Ensure validate_jq_expression limits (length, banned tokens) aren't being hit and shorten the program"],"exampleFix":"# before\njq:.prices[] | select(.amount > 100 and\n# after\njq:.prices[] | select(.amount > 100)","handlingStrategy":"validation","validationCode":"import jq\nfrom changedetectionio.html_tools import validate_jq_expression\n\ndef jq_ok(expr: str) -> bool:\n    try:\n        validate_jq_expression(expr)\n        jq.compile(expr)\n        return True\n    except ValueError:\n        return False","typeGuard":"def is_valid_jq(expr: str) -> bool:\n    try:\n        jq.compile(expr)\n        return True\n    except (ValueError, Exception):\n        return False","tryCatchPattern":"try:\n    jq.compile(expr)\nexcept ValueError as e:\n    # str(e) contains jq's compile error for display\n    ...","preventionTips":["Test filters with the jq CLI first","Keep programs short — built-in validation enforces size/complexity limits","Balance braces/quotes; remember jq is a program not a path language"],"tags":["jq","form-validation","expression-syntax"],"backgroundTag":"jq-expression-invalid","analyzedSha":"5d9c7c6da76340597243e8163c4f2439237fa0e8","analyzedAt":"2026-08-27T19:41:16.067Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}