{"record":{"id":"5c7da5edd88c8f68","repo":"pola-rs/polars","slug":"cannot-do-arithmetic-with-series-of-dtype-self-d","errorCode":null,"errorMessage":"cannot do arithmetic with Series of dtype: {self.dtype!r} and argument of type: {type(other).__name__!r}","messagePattern":"cannot do arithmetic with Series of dtype: (.+?) and argument of type: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/series/series.py","lineNumber":1085,"sourceCode":"            if isinstance(other, int):\n                pyseries = sequence_to_pyseries(self.name, [other])\n                _s = self._from_pyseries(pyseries).cast(Decimal(scale=0))._s\n            else:\n                _s = sequence_to_pyseries(self.name, [other], dtype=Decimal)\n\n            if \"rhs\" in op_ffi:\n                return self._from_pyseries(getattr(_s, op_s)(self._s))\n            else:\n                return self._from_pyseries(getattr(self._s, op_s)(_s))\n        else:\n            other = maybe_cast(other, self.dtype)\n            f = get_ffi_func(op_ffi, self.dtype, self._s)\n        if f is None:\n            msg = (\n                f\"cannot do arithmetic with Series of dtype: {self.dtype!r} and argument\"\n                f\" of type: {type(other).__name__!r}\"\n            )\n            raise TypeError(msg)\n        return self._from_pyseries(f(other))\n\n    @overload\n    def __add__(self, other: DataFrame) -> DataFrame: ...\n\n    @overload\n    def __add__(self, other: Expr) -> Expr: ...\n\n    @overload\n    def __add__(self, other: Any) -> Self: ...\n\n    def __add__(self, other: Any) -> Series | DataFrame | Expr:\n        if isinstance(other, str):\n            other = Series(\"\", [other])\n        elif isinstance(other, pl.DataFrame):\n            return other + self\n        elif isinstance(other, pl.Expr):\n            return F.lit(self) + other","sourceCodeStart":1067,"sourceCodeEnd":1103,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/py-polars/src/polars/series/series.py#L1067-L1103","documentation":"_arithmetic dispatches +, -, *, /, % to a dtype-specific FFI function. When no implementation exists for the combination of the Series' dtype and the operand's Python type, it raises TypeError describing both sides. Polars does not silently coerce arbitrary type pairs for arithmetic; the user must cast explicitly.","triggerScenarios":"Applying +, -, *, / or % between a Series and an operand of an unsupported type, e.g. string_series + 1, int_series + 'abc', or arithmetic on List/Struct/Object-typed Series.","commonSituations":"Forgetting to parse numeric columns read from CSV (they stay Utf8/String, so 'col' + 1 fails); mixing string concatenation with numeric literals; passing datetimes or lists as operands instead of scalars or matching-dtype Series.","solutions":["Cast the operand or Series to a compatible dtype first, e.g. s.cast(pl.Int64) + 1 for numeric strings, or s.str.to_datetime() for date-like strings.","For string concatenation, use explicit string APIs (s.str.concat / + between two Utf8 Series) — never Series + int.","Rewrite as an expression for more flexible coercion: s.to_frame().select(pl.col(name) + other), which also gives clearer dtype errors.","If mixing temporal and numeric types, cast the temporal column to Int64 first (s.cast(pl.Int64) or s.dt.epoch(...)) and re-cast afterwards."],"exampleFix":"// before\ns = pl.Series('n', ['1', '2', '3'])  # dtype Utf8\ns + 1  # TypeError: cannot do arithmetic with Series of dtype: String and argument of type: 'int'\n\n// after\ns.cast(pl.Int64) + 1","handlingStrategy":"validation","validationCode":"NUMERIC = (pl.Int8, pl.Int16, pl.Int32, pl.Int64, pl.UInt8, pl.UInt16, pl.UInt32, pl.UInt64, pl.Float32, pl.Float64)\nassert s.dtype in NUMERIC or not isinstance(other, (int, float)), \\\n    f'cast operands to a numeric dtype before arithmetic (got {s.dtype} and {type(other).__name__})'","typeGuard":"def arithmetic_compatible(dtype: pl.DataType, other) -> bool:\n    if isinstance(dtype, (pl.List, pl.Struct, pl.Object)):\n        return False\n    if dtype == pl.Utf8:\n        return isinstance(other, str) or (isinstance(other, pl.Series) and other.dtype == pl.Utf8)\n    return isinstance(other, (int, float, pl.Series))","tryCatchPattern":"try:\n    result = s + other\nexcept TypeError as e:\n    if 'cannot do arithmetic with Series of dtype' in str(e):\n        result = s.cast(pl.Int64) + other  # or str.to_datetime()/to_numeric() as appropriate\n    else:\n        raise","preventionTips":["Parse numeric columns explicitly after read_csv/read_parquet (schema overrides or str.to_numeric) so they are not Utf8.","Use expression API (df.select(pl.col('x') + 1)) which coerces more flexibly and yields clearer errors.","Never mix string and numeric operands; make concatenation vs addition explicit with str APIs or casts.","Keep temporal and numeric arithmetic separate: cast temporal to Int64 before numeric ops.","Unit-test arithmetic helpers with the dtypes your pipelines actually produce."],"tags":["python","polars","arithmetic","dtype","type-coercion"],"backgroundTag":"dtype-mismatch","analyzedSha":"fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e","analyzedAt":"2026-09-18T22:14:11.667Z","contentChangedAt":"2026-09-18T22:14:11.667Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}