unclecode/crawl4ai · error · ValueError
unsupported resource_types {bad}; allowed: {sorted(_ALLOWED_
Error message
unsupported resource_types {bad}; allowed: {sorted(_ALLOWED_RESOURCE_TYPES)} What it means
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.
Source
Thrown at deploy/docker/hook_registry.py:49
_HEADER_NAME_RE = re.compile(r"^[A-Za-z0-9-]{1,64}$")
_ALLOWED_RESOURCE_TYPES = {"image", "stylesheet", "font", "media"}
_MAX_SCROLL_STEPS = 50
_MAX_SCROLL_DELAY_MS = 5000
_MAX_WAIT_MS = 60_000
_MAX_COOKIES = 20
_MAX_HEADERS = 20
# ───────────────────────── per-action parameter schemas ─────────────────────────
class BlockResourcesParams(BaseModel):
resource_types: List[str] = Field(..., min_length=1)
@field_validator("resource_types")
@classmethod
def _check(cls, v):
bad = sorted(set(v) - _ALLOWED_RESOURCE_TYPES)
if bad:
raise ValueError(f"unsupported resource_types {bad}; allowed: {sorted(_ALLOWED_RESOURCE_TYPES)}")
return v
class _Cookie(BaseModel):
name: str = Field(..., min_length=1, max_length=256)
value: str = Field(..., max_length=4096)
domain: str = Field(..., min_length=1, max_length=253)
path: str = "/"
secure: bool = True
httpOnly: bool = False
class AddCookiesParams(BaseModel):
cookies: List[_Cookie] = Field(..., min_length=1, max_length=_MAX_COOKIES)
class SetHeadersParams(BaseModel):
headers: Dict[str, str]View on GitHub (pinned to 7e80152142)
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.
Example fix
# before
{"action": "block_resources", "params": {"resource_types": ["script", "images"]}}
# after
{"action": "block_resources", "params": {"resource_types": ["image", "media"]}} Defensive patterns
Strategy: validation
Validate before calling
ALLOWED_RESOURCE_TYPES = {"image", "stylesheet", "font", "media"}
def valid_block_resources(spec: dict) -> bool:
if spec.get("action") != "block_resources":
return False
rt = spec.get("params", {}).get("resource_types")
return isinstance(rt, list) and len(rt) > 0 and set(rt) <= ALLOWED_RESOURCE_TYPES Type guard
def is_resource_type_list(v) -> bool:
return isinstance(v, list) and len(v) > 0 and all(isinstance(x, str) and x in {"image", "stylesheet", "font", "media"} for x in v) Try / catch
from hook_registry import build_declarative_hooks, HookValidationError
try:
hooks = build_declarative_hooks(specs)
except HookValidationError as e:
raise ConfigError(f"hook config rejected: {e}") from e Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- too many headers (max {_MAX_HEADERS})
- invalid params for hook '{action}': {e}
- Hook '{hook_name}' must be a callable function, got {type(ho
- invalid header name {name!r}
- control characters in value for header {name!r}
AI-assisted analysis of unclecode/crawl4ai@7e80152142 (2026-08-14).
Data as JSON: /api/errors/ba72ff52dc7471af.
Report an issue: GitHub.