diff --git a/crawl4ai/async_configs.py b/crawl4ai/async_configs.py index e7946f0a6..da3df8769 100644 --- a/crawl4ai/async_configs.py +++ b/crawl4ai/async_configs.py @@ -242,8 +242,18 @@ def from_serializable_dict(data: Any) -> Any: if isinstance(data, (str, int, float, bool)): return data - # Handle typed data - if isinstance(data, dict) and "type" in data: + # Handle typed data. + # Only enter the typed-object path for dicts that match the shapes produced + # by to_serializable_dict(): {"type": "", "params": {...}} or + # {"type": "dict", "value": {...}}. Plain business dicts that happen to + # carry a "type" key (e.g. JSON-Schema fragments, JsonCss field specs like + # {"type": "text", "name": "..."}) have neither "params" nor "value" and + # must fall through to the raw-dict path below so they are passed as data. + if ( + isinstance(data, dict) + and "type" in data + and ("params" in data or (data["type"] == "dict" and "value" in data)) + ): # Handle plain dictionaries if data["type"] == "dict" and "value" in data: return {k: from_serializable_dict(v) for k, v in data["value"].items()}