Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't suggest -- in errors if it isn't relevant #2766

Open
2 tasks done
silvioprog opened this issue Sep 9, 2021 · 13 comments
Open
2 tasks done

Don't suggest -- in errors if it isn't relevant #2766

silvioprog opened this issue Sep 9, 2021 · 13 comments
Assignees
Labels
A-help Area: documentation, including docs.rs, readme, examples, etc... C-enhancement Category: Raise on the bar on expectations E-medium Call for participation: Experience needed to fix: Medium / intermediate

Comments

@silvioprog
Copy link

silvioprog commented Sep 9, 2021

Please complete the following tasks

  • I have searched the discussions
  • I have searched the existing issues

Clap Version

3.0.0-beta.4

Describe your use case

Hi.

Assuming I have an args.rs file:

use clap::Clap;

#[derive(Debug, Clap)]
pub struct Args {
    #[clap(short)]
    pub metric: bool,
    #[clap(short)]
    pub imperial: bool,
}

and a main.rs:

use clap::Clap;

mod args;

fn main() {
    let args = args::Args::parse();
    println!("{:?}", args);
}

if I call the executable like this (passing an invalid flag):

./target/debug/teste -d

it returns this message:

error: Found argument '-d' which wasn't expected, or isn't valid in this context

        If you tried to supply `-d` as a value rather than a flag, use `-- -d`

USAGE:
    teste [FLAGS]

For more information try --help

Describe the solution you'd like

It would be nice any global configuration in Clap to avoid suggestions like -- -x. The message would be like this, which is much clear for the user (since the application contains only two optional flags):

error: Found argument '-d' which wasn't expected, or isn't valid in this context

USAGE:
    teste [FLAGS]

For more information try --help

or:

error: Found argument '-d' which wasn't expected, or isn't valid

USAGE:
    teste [FLAGS]

For more information try --help

or even:

error: Found argument '-d' which isn't valid

USAGE:
    teste [FLAGS]

For more information try --help

Alternatives, if applicable

No response

Additional Context

No response

@pksunkara pksunkara added C-enhancement Category: Raise on the bar on expectations and removed T: new feature labels Sep 9, 2021
@pksunkara
Copy link
Member

@ldm0 Can we skip that if the subcommand we are parsing doesn't have any args with multiple values?

@ldm0 ldm0 self-assigned this Sep 10, 2021
@epage epage added A-help Area: documentation, including docs.rs, readme, examples, etc... and removed C: errors labels Dec 8, 2021
@epage epage changed the title Allow to show less verbose messages or avoid unsupported suggestions Don't suggest -- in errors if it isn't relevant Dec 13, 2021
@epage epage added E-medium Call for participation: Experience needed to fix: Medium / intermediate and removed D: easy labels Dec 13, 2021
@matklad
Copy link
Contributor

matklad commented Oct 13, 2022

Two extra points:

  • this is a regression from clap2
  • subjectively, this is feels like a huge problem:
    • it's very easy for the end-user to trigger this behavior (eg, anything with subcommands with non-global optiosn)
    • wrong error suggestions make it much harder for the end-user to fix their problem
    • the particular way this plays out is quite frustrating for the end user

@epage
Copy link
Member

epage commented Oct 13, 2022

For extra context, #1284 is the original issue and #1514 is the original PR

@epage
Copy link
Member

epage commented Oct 13, 2022

@matklad could you expand further on those points so that we better balance the different needs when coming up with a solution.

For example

it's very easy for the end-user to trigger this behavior (eg, anything with subcommands with non-global optiosn)

I'm assuming the problem is: "When running a subcommand, I assumed some flags were global and put them after the subcommand and it failed, producing this message which doesn't apply to my situation"

If we made the message conditioned on there being positional arguments, that'll make it so we never show it when it isn't applicable but it can still show up in the workflow you mentioned if the subcommand has positional arguments. This is one of the points I'm trying to understand since by the direction and strength of your comments it sounds like that wouldn't be acceptable but I want to understand why.

the particular way this plays out is quite frustrating for the end user

What was it that was so frustrating with it? If you ended up going down the wrong path, what was it about the message that you went that way? I'm trying to understand what is so frustrating about this when to me it clearly articulates when the suggestion is relevant. This doesn't mean that you wrong but that you have a different perspective that we need to incorporate in handling this.

@matklad
Copy link
Contributor

matklad commented Oct 13, 2022

I'm assuming the problem is: "When running a subcommand, I assumed some flags were global and put them after the subcommand and it failed, producing this message which doesn't apply to my situation"

Yeah. And, in particular, this seems to be a very frequent problem, rather than an obscure edge case. More generally, it seems to me that more or less any mistake in the args leads to "If you tried to supply ..." message (although often with a more relevant suggestion as well), but the probability that I actually indeed meant to pass -- is very low. It's a bit like if rustc added "you could try unsafe { &(*x as *const _)}" as a suggestion for "variable does not live long enough" error. There are rare cases where that'd be a correct suggestion, but they are very rare.

What was it that was so frustrating with it?

Several things:

  • confident wrong suggestion which sends me down the wrong path
  • the fact that if I try to follow the suggestion, I got echoed the same advice
λ cargo run -p neard -- init --home h
    Finished dev [unoptimized + debuginfo] target(s) in 0.16s
     Running `target/debug/neard init --home h`
error: Found argument '--home' which wasn't expected, or isn't valid in this context

	If you tried to supply `--home` as a value rather than a flag, use `-- --home`

USAGE:
    neard init [OPTIONS]
λ cargo run -p neard -- init -- --home h
    Finished dev [unoptimized + debuginfo] target(s) in 0.16s
     Running `target/debug/neard init -- --home h`
error: Found argument '--home' which wasn't expected, or isn't valid in this context

	If you tried to supply `--home` as a value rather than a flag, use `-- --home`

USAGE:
    neard init [OPTIONS]

For more information try --help
  • the realization that not only it's a wrong suggestion for my situation, but that this can't be a correct suggestion at all (because there's nothing to take the value in this particular CLI)

More generally, features which make life more complicated with comparison to a hypothetical where such feature did't exist create a feeling of frustration.

@epage
Copy link
Member

epage commented Oct 13, 2022

confident wrong suggestion which sends me down the wrong path

It had a condition on the suggestion. What was unclear about the condition that you thought it applied (since you were trying to pass a flag instead of a value)? Or is it a case of "scan and just do what it says", missing the condition?

@epage
Copy link
Member

epage commented Oct 13, 2022

but the probability that I actually indeed meant to pass -- is very low

I can understand in this case. I have personally been in the same situation as #1284 many times and haven't even considered using -- and would have found this helpful.

@matklad
Copy link
Contributor

matklad commented Oct 13, 2022

Or is it a case of "scan and just do what it says", missing the condition?

Exactly this: I am a user in a hurry, whose mind is occupied by an unrelated problem. I don't have mental space to carefully consider if-then-else clauses. If a tool suggests some solution, my assumption is that that indeed is the most probable fix.

many times and haven't even considered using -- and would have found this helpful.

Exactly: there are some specific contexts where -- is useful, but they are rare in comparison to all the contexts where -- is not useful. Off the top of my head, I recall only two instances where I do want to pass --foo as a value:

  • "take the rest of the argumetns to pass through to another binary" (cargo run)
  • "needle" argument for text searches

That's sort of Bayes' rule, baseline probabilities matter.

There's a bunch of ways we can make this more specific:

  • don't suggest if the suggestion is guaranteed to be wrong
  • suggest only when we do expect a value and miss one (mandatory positional arg or switch)
  • suggest only in highly-likely situations (trailing args pattern)
  • add API to flag a specific argument with "hey, the value here might start with -", which would affect both default help and error messages.

@epage
Copy link
Member

epage commented Oct 13, 2022

For now, #4380 limits the -- suggestion to only if

  • -- hasn't already been used
  • positional arguments exist
  • a short or long was passed in (refinement of existing condition)

Something I've also been considering for both clap and cargo is following the rustc diagnostic guidelines of not suggesting things to users but informing users what exist.

EDIT: To be clear, I'm leaving this open to encourage further discussion on the overall direction

epage added a commit to epage/clap that referenced this issue Oct 13, 2022
From
https://rustc-dev-guide.rust-lang.org/diagnostics.html#suggestion-style-guide

> Suggestions should not be a question. In particular, language like
> "did you mean" should be avoided. Sometimes, it's unclear why a
> particular suggestion is being made. In these cases, it's better to be
> upfront about what the suggestion is.
>
> The message may contain further instruction such as "to do xyz, use"
> or "to do xyz, use abc".

Inspired by clap-rs#2766
@epage
Copy link
Member

epage commented Oct 13, 2022

I've created #4385 to tweak the wording of the suggestions. It could probably use some more work and I'm hesitant in doing a change like this in a patch release as people might design some of their own CLI to match clap and changing it could provide a degraded experience, so we might want to call attention to this by saving it for a minor release.

@epage
Copy link
Member

epage commented Oct 13, 2022

v4.0.15 is released with #4380.

@Nemo157
Copy link
Contributor

Nemo157 commented Jun 29, 2023

#4380 (or changes since then since that was quite some time ago) doesn't help with subcommands:

> sshagmux lis
error: unrecognized subcommand 'lis'

  tip: a similar subcommand exists: 'list'
  tip: to pass 'lis' as a value, use 'sshagmux -- lis'

Usage: sshagmux <COMMAND>

For more information, try '--help'.

There is nowhere for "values" to go, and in fact trying to use this form emits the exact same error message

> sshagmux -- lis
error: unrecognized subcommand 'lis'

  tip: a similar subcommand exists: 'list'
  tip: to pass 'lis' as a value, use 'sshagmux -- lis'

Usage: sshagmux <COMMAND>

For more information, try '--help'.

@epage
Copy link
Member

epage commented Jul 21, 2023

That is fixed in v4.3.18 by #5033

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-help Area: documentation, including docs.rs, readme, examples, etc... C-enhancement Category: Raise on the bar on expectations E-medium Call for participation: Experience needed to fix: Medium / intermediate
Projects
None yet
Development

No branches or pull requests

6 participants