{"record":{"id":"53172d34f0cd248f","repo":"D4Vinci/Scrapling","slug":"can-t-convert-type-value-name-to-bytes","errorCode":null,"errorMessage":"Can't convert {type(value).__name__} to bytes","messagePattern":"Can't convert (.+?) to bytes","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"scrapling/spiders/request.py","lineNumber":20,"sourceCode":"from io import BytesIO\nfrom functools import cached_property\nfrom urllib.parse import urlparse, urlencode\n\nimport orjson\nfrom w3lib.url import canonicalize_url\n\nfrom scrapling.engines.toolbelt.custom import Response\nfrom scrapling.core._types import Any, AsyncGenerator, Callable, Dict, Optional, Union, Tuple, TYPE_CHECKING\n\nif TYPE_CHECKING:\n    from scrapling.spiders.spider import Spider\n\n\ndef _convert_to_bytes(value: str | bytes) -> bytes:\n    if isinstance(value, bytes):\n        return value\n    if not isinstance(value, str):\n        raise TypeError(f\"Can't convert {type(value).__name__} to bytes\")\n\n    return value.encode(encoding=\"utf-8\", errors=\"ignore\")\n\n\ndef _stable_value_repr(value: Any) -> str:\n    try:\n        return orjson.dumps(value, option=orjson.OPT_SORT_KEYS, default=repr).decode()\n    except TypeError:\n        return repr(value)\n\n\nclass Request:\n    def __init__(\n        self,\n        url: str,\n        sid: str = \"\",\n        callback: Callable[[Response], AsyncGenerator[Union[Dict[str, Any], \"Request\", None], None]] | None = None,\n        priority: int = 0,","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/D4Vinci/Scrapling/blob/5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f/scrapling/spiders/request.py#L2-L38","documentation":"The internal helper _convert_to_bytes accepts only str and bytes. Request bodies/headers constructed with any other type (int, float, dict, None) hit this TypeError, which names the offending type. Note that dicts/JSON are not auto-serialized — you must encode them yourself.","triggerScenarios":"Request(url, body={'q': 'x'}), Request(url, data=123), or a header value computed as an int (e.g. content_length=size) rather than str(size).","commonSituations":"Passing a parsed JSON payload straight back as a body; building headers from numeric variables; a None default leaking into a body argument.","solutions":["JSON-encode dict/list bodies first: body=orjson.dumps(payload) or json.dumps(payload).encode().","Convert numerics: str(value) for headers, str(value).encode() for bodies.","Guard against None: body = body if body is not None else b''."],"exampleFix":"# before\nRequest(url, body={'q': 'x'})  # TypeError: Can't convert dict to bytes\n\n# after\nimport json\nRequest(url, body=json.dumps({'q': 'x'}).encode('utf-8'))","handlingStrategy":"type-guard","validationCode":"def as_body(value) -> bytes:\n    if value is None:\n        return b''\n    if isinstance(value, bytes):\n        return value\n    if isinstance(value, str):\n        return value.encode('utf-8')\n    if isinstance(value, (dict, list)):\n        return json.dumps(value).encode('utf-8')\n    raise TypeError(f'unsupported body type {type(value).__name__}')\n\nRequest(url, body=as_body(payload))","typeGuard":"def is_str_or_bytes(v) -> bool:\n    return isinstance(v, (str, bytes))","tryCatchPattern":null,"preventionTips":["Encode JSON bodies explicitly before constructing a Request.","Stringify numeric header values at the point of header construction."],"tags":["request","bytes","validation","type-error"],"backgroundTag":null,"analyzedSha":"5d213a2d4764002bfc4fed33c32fe09fa8b0bf7f","analyzedAt":"2026-08-14T22:23:09.440Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}