diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7d764f35a90c8c1f09a4f5d7ce7384ed3f3bab0e..f0b5c978582b70a5024f78793877ee670099ad86 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,4 @@
 # v2.23.2
 
 * some docs updates for IntervalTerminableThread
+* added better error code for invalid number of arguments in for_argument
diff --git a/satella/__init__.py b/satella/__init__.py
index 7048ba0127d688ef09991c3bdf22b528e78f4531..1864b194cd0c07fbf5c31d313a59d8925cb18d51 100644
--- a/satella/__init__.py
+++ b/satella/__init__.py
@@ -1 +1 @@
-__version__ = '2.23.3a2'
+__version__ = '2.23.3'
diff --git a/satella/coding/decorators/arguments.py b/satella/coding/decorators/arguments.py
index cc0a712d1fad92e2f4b6cf9ab1b2283be4ecd39c..cf25789308bb6124430532f20e723d4a22725c20 100644
--- a/satella/coding/decorators/arguments.py
+++ b/satella/coding/decorators/arguments.py
@@ -364,7 +364,7 @@ def for_argument(*t_ops: ForArgumentArg, **t_kwops: ForArgumentArg):
             @wraps(fun)
             def inner(*args, **kwargs):
                 # add extra 'None' argument if unbound method
-                assert len(args) >= len(t_ops)
+                assert len(args) >= len(t_ops), 'Invalid number of arguments'
                 a = fun(*((_NOP if op2 is None else op2)(arg) for arg, op2 in
                           itertools.zip_longest(args, t_ops, fillvalue=None)),
                         **{k: t_kwops.get(k, _NOP)(v) for k, v in kwargs.items()})