diff --git a/tests/test_type_conversion.py b/tests/test_type_conversion.py index 83edd1ecb5..86afa5b882 100644 --- a/tests/test_type_conversion.py +++ b/tests/test_type_conversion.py @@ -168,3 +168,15 @@ def custom_click_type( result = runner.invoke(app, ["0x56"]) assert result.exit_code == 0 + + +def test_multiple_list_arguments_error(): + """Test that multiple List arguments raises a clear error (issue #260).""" + app = typer.Typer() + + @app.command() + def cmd(names: list[str], others: list[str]): + print(f"names={names}, others={others}") + + with pytest.raises(click.UsageError, match="Only one argument can take multiple values"): + runner.invoke(app, ["a", "b"], catch_exceptions=False) diff --git a/typer/main.py b/typer/main.py index f4f21bb844..bcd0dc6bc3 100644 --- a/typer/main.py +++ b/typer/main.py @@ -1376,6 +1376,16 @@ def get_params_convertors_ctx_param_name_from_function( if convertor: convertors[param_name] = convertor params.append(click_param) + variadic_args = [ + p.name for p in params if isinstance(p, click.Argument) and p.nargs < 0 + ] + if len(variadic_args) > 1: + names = ", ".join(f"'{n}'" for n in variadic_args) + raise click.UsageError( + f"Only one argument can take multiple values (nargs=-1), but " + f"{len(variadic_args)} were found: {names}. " + f"Use List[...] (or Sequence[...]) for at most one argument." + ) return params, convertors, context_param_name