A hack for aggressive type-checking?

With the definition

f[x_List] := x + 1

you create a substitution rule that can only be applied when the argument of f is a List. In all other cases the function remains unevaluated. If instead you want to see an error message, or maybe no output, or whatever, you have to define a substitution rule for f that is applied in all other cases. That is most easily done in the following way:

f[_] = "Whatever you want";

That this rule is not used for arguments being a List is due to the fact that Mathematica uses the most restrictive rule first; that is the rule with argument restricted to a List.

f[1]

(* "Whatever you want" *)

f[{1}]

(* {2} *)

In general there are multiple reasons why a function could fail and it would be better to know the specific reason--particularly if it has been some time since the code was written.

See the documentation for Message

Clear[f]

f[x_] /; If[Head[x] === List, True,
   Message[f::arg, x]; False] := x + 1

f::arg = "The argument `1` is not a list.";

f[{1, 1}]

(*  {2, 2}  *)

f[1]

(*  f::arg: The argument 1 is not a list.

f[1]  *)