diff --git a/src/main/wacc/Error.scala b/src/main/wacc/Error.scala
index 077c83f..c627246 100644
--- a/src/main/wacc/Error.scala
+++ b/src/main/wacc/Error.scala
@@ -6,8 +6,8 @@ import wacc.types._
 enum Error {
   case DuplicateDeclaration(ident: ast.Ident)
   case UndefinedIdentifier(ident: ast.Ident, identType: renamer.IdentType)
-  case FunctionParamsMismatch(expected: Int, got: Int) // TODO not fine
 
+  case FunctionParamsMismatch(pos: Position, expected: Int, got: Int)
   case SemanticError(pos: Position, msg: String)
   case TypeMismatch(pos: Position, expected: SemType, got: SemType, msg: String)
   case InternalError(pos: Position, msg: String)
diff --git a/src/main/wacc/typeChecker.scala b/src/main/wacc/typeChecker.scala
index 9e86b58..e58b408 100644
--- a/src/main/wacc/typeChecker.scala
+++ b/src/main/wacc/typeChecker.scala
@@ -176,7 +176,10 @@ object typeChecker {
     case Call(id, args) =>
       val funcTy = ctx.typeOf(id)
       funcTy match {
-        case KnownType.Func(retTy, paramTys) => // TODO do we check argument lengths match
+        case KnownType.Func(retTy, paramTys) =>
+          if (args.length != paramTys.length) {
+            ctx.error(Error.FunctionParamsMismatch(id.pos, paramTys.length, args.length))
+          }
           args.zip(paramTys).foreach { case (arg, paramTy) =>
             checkValue(arg, Constraint.Is(paramTy, s"argument type mismatch in function ${id.v}"))
           }