{"record":{"id":"ba72ff52dc7471af","repo":"unclecode/crawl4ai","slug":"unsupported-resource-types-bad-allowed-sorted","errorCode":null,"errorMessage":"unsupported resource_types {bad}; allowed: {sorted(_ALLOWED_RESOURCE_TYPES)}","messagePattern":"unsupported resource_types (.+?); allowed: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"deploy/docker/hook_registry.py","lineNumber":49,"sourceCode":"_HEADER_NAME_RE = re.compile(r\"^[A-Za-z0-9-]{1,64}$\")\n_ALLOWED_RESOURCE_TYPES = {\"image\", \"stylesheet\", \"font\", \"media\"}\n_MAX_SCROLL_STEPS = 50\n_MAX_SCROLL_DELAY_MS = 5000\n_MAX_WAIT_MS = 60_000\n_MAX_COOKIES = 20\n_MAX_HEADERS = 20\n\n\n# ───────────────────────── per-action parameter schemas ─────────────────────────\nclass BlockResourcesParams(BaseModel):\n    resource_types: List[str] = Field(..., min_length=1)\n\n    @field_validator(\"resource_types\")\n    @classmethod\n    def _check(cls, v):\n        bad = sorted(set(v) - _ALLOWED_RESOURCE_TYPES)\n        if bad:\n            raise ValueError(f\"unsupported resource_types {bad}; allowed: {sorted(_ALLOWED_RESOURCE_TYPES)}\")\n        return v\n\n\nclass _Cookie(BaseModel):\n    name: str = Field(..., min_length=1, max_length=256)\n    value: str = Field(..., max_length=4096)\n    domain: str = Field(..., min_length=1, max_length=253)\n    path: str = \"/\"\n    secure: bool = True\n    httpOnly: bool = False\n\n\nclass AddCookiesParams(BaseModel):\n    cookies: List[_Cookie] = Field(..., min_length=1, max_length=_MAX_COOKIES)\n\n\nclass SetHeadersParams(BaseModel):\n    headers: Dict[str, str]","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/deploy/docker/hook_registry.py#L31-L67","documentation":"A pydantic field_validator on BlockResourcesParams.resource_types rejects any value outside _ALLOWED_RESOURCE_TYPES = {\"image\", \"stylesheet\", \"font\", \"media\"}. The message lists the offending types and the allowed set. It fires when declarative hook specs are validated (build_declarative_hooks), surfacing as a HookValidationError wrapping this ValueError.","triggerScenarios":"Passing a block_resources hook spec with resource_types like [\"script\", \"xhr\"] or [\"document\"] or a typo like [\"stylesheets\"]; anything not exactly one of image/stylesheet/font/media.","commonSituations":"Copying CDP resource type names (script, xhr, fetch, websocket) from DevTools or Playwright docs into a crawl config; assuming all Chromium resource types are blockable; pluralization/typo mistakes.","solutions":["Use only the four supported values: image, stylesheet, font, media.","If you need to block scripts, use the crawler's other options (e.g. page load / JS settings in crawler_config) rather than this hook.","Catch HookValidationError around build_declarative_hooks and report the allowed list to the config author."],"exampleFix":"# before\n{\"action\": \"block_resources\", \"params\": {\"resource_types\": [\"script\", \"images\"]}}\n\n# after\n{\"action\": \"block_resources\", \"params\": {\"resource_types\": [\"image\", \"media\"]}}","handlingStrategy":"validation","validationCode":"ALLOWED_RESOURCE_TYPES = {\"image\", \"stylesheet\", \"font\", \"media\"}\n\ndef valid_block_resources(spec: dict) -> bool:\n    if spec.get(\"action\") != \"block_resources\":\n        return False\n    rt = spec.get(\"params\", {}).get(\"resource_types\")\n    return isinstance(rt, list) and len(rt) > 0 and set(rt) <= ALLOWED_RESOURCE_TYPES","typeGuard":"def is_resource_type_list(v) -> bool:\n    return isinstance(v, list) and len(v) > 0 and all(isinstance(x, str) and x in {\"image\", \"stylesheet\", \"font\", \"media\"} for x in v)","tryCatchPattern":"from hook_registry import build_declarative_hooks, HookValidationError\n\ntry:\n    hooks = build_declarative_hooks(specs)\nexcept HookValidationError as e:\n    raise ConfigError(f\"hook config rejected: {e}\") from e","preventionTips":["Keep the allowed set (image/stylesheet/font/media) next to your config generator.","Map DevTools resource names to the supported four before writing specs.","Run build_declarative_hooks on configs in CI to catch invalid specs pre-deploy."],"tags":["validation","pydantic","hooks","crawler"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}