pola-rs/polars · error · TypeError
`new` argument is required if `old` argument is not a Mappin
Error message
`new` argument is required if `old` argument is not a Mapping type
What it means
Expr.replace(old, new) raises TypeError when `new` is omitted and `old` is not a Mapping. The two supported call shapes are replace(mapping) (dict of old->new) or replace(old, new) with both positional arguments; a bare scalar/list old with no new is meaningless. Note the check uses the NO_DEFAULT sentinel, so new=None does not satisfy it either.
Source
Thrown at py-polars/src/polars/expr/expr.py:12268
" Use `replace_strict` instead to set a return data type while replacing values.",
version="1.0.0",
)
if default is not NO_DEFAULT:
issue_deprecation_warning(
"the `default` parameter for `replace` is deprecated."
" Use `replace_strict` instead to set a default while replacing values.",
version="1.0.0",
)
return self.replace_strict(
old, new, default=default, return_dtype=return_dtype
)
if new is NO_DEFAULT:
if not isinstance(old, Mapping):
msg = (
"`new` argument is required if `old` argument is not a Mapping type"
)
raise TypeError(msg)
new = list(old.values())
old = list(old.keys())
else:
if isinstance(old, Sequence) and not isinstance(old, (str, pl.Series)):
old = pl.Series(old)
if isinstance(new, Sequence) and not isinstance(new, (str, pl.Series)):
new = pl.Series(new)
old_pyexpr = parse_into_expression(old, str_as_lit=True) # type: ignore[arg-type]
new_pyexpr = parse_into_expression(new, str_as_lit=True)
result = wrap_expr(self._pyexpr.replace(old_pyexpr, new_pyexpr))
if return_dtype is not None:
result = result.cast(return_dtype)
return result
View on GitHub (pinned to df599052da)
Solutions
- Pass both arguments: pl.col('a').replace(2, 10).
- Or pass a dict: pl.col('a').replace({2: 10, 3: 30}).
- In wrapper functions, use a sentinel (NO_DEFAULT-style object), not None, to detect 'not provided'.
Example fix
# before
pl.col('a').replace(2)
# after
pl.col('a').replace(2, 10)
# or
pl.col('a').replace({2: 10}) Defensive patterns
Strategy: type-guard
Validate before calling
from collections.abc import Mapping
if new is None and not isinstance(old, Mapping):
raise TypeError('replace needs `new` unless `old` is a mapping') Type guard
from collections.abc import Mapping
def has_full_replace_args(old, new) -> bool:
return isinstance(old, Mapping) or new is not None Prevention
- Default wrapper parameters to a sentinel object, never None, for arguments where None is not a valid value.
- Prefer the dict form replace({...}) for multi-value mappings.
When it happens
Trigger: pl.col('a').replace(2), pl.col('a').replace([1, 2]) without new, or replace(old=2, new=None) via optional parameters that default to None.
Common situations: Wrapping replace in a helper where new is optional (default None instead of NO_DEFAULT); assuming old alone is a no-op filter; upgrading code where a default value used to be positional.
Related errors
- cannot specify both `value` and `strategy`
- must specify either a fill `value` or `strategy`
- strategy {strategy!r} is not supported
- reinterpret requires exactly one of `signed` or `dtype` to b
- cannot specify both `n` and `fraction`
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/9f82f5a17fd618a8.
Report an issue: GitHub.