{"record":{"id":"c6acedf2576d2cf6","repo":"boto/boto3","slug":"infinity-and-nan-not-supported","errorCode":null,"errorMessage":"Infinity and NaN not supported","messagePattern":"Infinity and NaN not supported","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"boto3/dynamodb/types.py","lineNumber":216,"sourceCode":"        if isinstance(value, collections_abc.Mapping):\n            return True\n        return False\n\n    def _is_listlike(self, value):\n        if isinstance(value, (list, tuple)):\n            return True\n        return False\n\n    def _serialize_null(self, value):\n        return True\n\n    def _serialize_bool(self, value):\n        return value\n\n    def _serialize_n(self, value):\n        number = str(DYNAMODB_CONTEXT.create_decimal(value))\n        if number in ['Infinity', 'NaN']:\n            raise TypeError('Infinity and NaN not supported')\n        return number\n\n    def _serialize_s(self, value):\n        return value\n\n    def _serialize_b(self, value):\n        if isinstance(value, Binary):\n            value = value.value\n        return value\n\n    def _serialize_ss(self, value):\n        return [self._serialize_s(s) for s in value]\n\n    def _serialize_ns(self, value):\n        return [self._serialize_n(n) for n in value]\n\n    def _serialize_bs(self, value):\n        return [self._serialize_b(b) for b in value]","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/boto/boto3/blob/6e10b029c1326a437932a8b24f38af69fd986e15/boto3/dynamodb/types.py#L198-L234","documentation":"TypeSerializer._serialize_n converts the value to a Decimal via DYNAMODB_CONTEXT.create_decimal and stringifies it. DynamoDB rejects the special decimal values Infinity and NaN, so boto3 raises TypeError('Infinity and NaN not supported') when the stringified form is one of those.","triggerScenarios":"Storing float('inf'), float('nan'), Decimal('Infinity'), Decimal('NaN'), or arithmetic that yields them (e.g. division by zero with Decimal context allowing it).","commonSituations":"Aggregations/statistics producing NaN from divide-by-zero; sensor data with inf; migrating NaN values from pandas.","solutions":["Filter or replace inf/NaN before storage (e.g. use None for missing, or a sentinel Decimal('0')).","Guard numeric inputs with math.isfinite or Decimal.is_finite().","Validate at the boundary: reject rows whose numeric fields are not finite."],"exampleFix":"# before\nfrom decimal import Decimal\ntable.put_item(Item={'ratio': Decimal('NaN')})\n# after\nimport math\nfrom decimal import Decimal\nval = Decimal('NaN')\nsafe = val if val.is_finite() else None\ntable.put_item(Item={'ratio': safe})","handlingStrategy":"validation","validationCode":"from decimal import Decimal\nimport math\ndef finite_decimal(v):\n    d = v if isinstance(v, Decimal) else Decimal(str(v))\n    if not d.is_finite():\n        raise ValueError(f'non-finite numeric: {v!r}')\n    return d","typeGuard":"from decimal import Decimal\ndef is_finite_decimal(v) -> bool:\n    try:\n        d = v if isinstance(v, Decimal) else Decimal(str(v))\n    except Exception:\n        return False\n    return d.is_finite()","tryCatchPattern":"try:\n    table.put_item(Item=item)\nexcept TypeError as e:\n    if 'Infinity and NaN' in str(e):\n        item = {k: (None if (isinstance(v, Decimal) and not v.is_finite()) else v)\n                for k, v in item.items()}\n        table.put_item(Item=item)\n    else:\n        raise","preventionTips":["Filter non-finite values out of statistics before storage.","Use Decimal and call is_finite() at the boundary.","Replace NaN/inf with None or a sentinel value intentionally."],"tags":["dynamodb","types","number","serialization","boto3"],"backgroundTag":null,"analyzedSha":"6e10b029c1326a437932a8b24f38af69fd986e15","analyzedAt":"2026-08-11T20:52:47.213Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}