{"record":{"id":"055b980742b114c8","repo":"aio-libs/aiohttp","slug":"data-cannot-be-decoded-with-s-encoding","errorCode":null,"errorMessage":"data cannot be decoded with %s encoding","messagePattern":"data cannot be decoded with (.+?) encoding","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"aiohttp/multipart.py","lineNumber":517,"sourceCode":"        data = await self.read(decode=True)\n        if not data:\n            return None\n        encoding = encoding or self.get_charset(default=\"utf-8\")\n        return cast(dict[str, Any], json.loads(data.decode(encoding)))\n\n    async def form(self, *, encoding: str | None = None) -> list[tuple[str, str]]:\n        \"\"\"Like read(), but assumes that body parts contain form urlencoded data.\"\"\"\n        data = await self.read(decode=True)\n        if not data:\n            return []\n        if encoding is not None:\n            real_encoding = encoding\n        else:\n            real_encoding = self.get_charset(default=\"utf-8\")\n        try:\n            decoded_data = data.rstrip().decode(real_encoding)\n        except UnicodeDecodeError:\n            raise ValueError(\"data cannot be decoded with %s encoding\" % real_encoding)\n\n        return parse_qsl(\n            decoded_data,\n            keep_blank_values=True,\n            encoding=real_encoding,\n        )\n\n    def at_eof(self) -> bool:\n        \"\"\"Returns True if the boundary was reached or False otherwise.\"\"\"\n        return self._at_eof\n\n    def _apply_content_transfer_decoding(self, data: bytes) -> bytes:\n        \"\"\"Apply Content-Transfer-Encoding decoding if header is present.\"\"\"\n        if CONTENT_TRANSFER_ENCODING in self.headers:\n            return self._decode_content_transfer(data)\n        return data\n\n    def _needs_content_decoding(self) -> bool:","sourceCodeStart":499,"sourceCodeEnd":535,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/multipart.py#L499-L535","documentation":"Raised by BodyPartReader.form() when the collected form-urlencoded bytes cannot be decoded using the resolved charset (explicit encoding argument, the part's Content-Type charset, or UTF-8 default). The original UnicodeDecodeError is converted to a ValueError.","triggerScenarios":"Calling await part.form() on a part whose bytes are not valid in the declared charset; e.g. Latin-1 bytes with a UTF-8 Content-Type, or binary garbage in a text field.","commonSituations":"Browsers sending form fields in the page's legacy encoding while the part header claims UTF-8; misconfigured server-side charset; binary data posted into a text form control; cross-encoding proxies.","solutions":["Pass the correct encoding explicitly: await part.form(encoding='latin-1').","Fix the producer to send a Content-Type charset that matches the bytes, or to send UTF-8.","If you need raw bytes, use read(decode=False) instead of form() and decode defensively with errors='replace'.","Validate the declared charset against the bytes (try .decode) before calling form()."],"exampleFix":"// before\nform = await part.form()\n\n// after\nform = await part.form(encoding='latin-1')","handlingStrategy":"validation","validationCode":"async def safe_form(part, *, fallback='utf-8'):\n    raw = await part.read(decode=True)\n    enc = part.get_charset(default=fallback)\n    try:\n        raw.decode(enc)\n    except UnicodeDecodeError:\n        enc = fallback\n    return await part.form(encoding=enc)","typeGuard":"def decodable_with(raw: bytes, encoding: str) -> bool:\n    try:\n        raw.decode(encoding)\n    except UnicodeDecodeError:\n        return False\n    return True","tryCatchPattern":"try:\n    form = await part.form(encoding='utf-8')\nexcept ValueError as e:\n    # bytes are not valid in the declared charset\n    form = await part.form(encoding='latin-1')  # fallback","preventionTips":["Send a Content-Type charset that matches the actual bytes.","Pass the explicit encoding argument to form() when you know it.","Read raw bytes with read(decode=False) and decode defensively when charset is untrusted."],"tags":["multipart","form-data","charset","encoding","unicode"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}