MCPcopy
hub / github.com/larksuite/cli / unknownSubcommandRunE

Function unknownSubcommandRunE

cmd/root.go:368–427  ·  view source on GitHub ↗

unknownSubcommandRunE replaces cobra's silent help fallback on group commands with a typed *errs.ValidationError: a flag that belongs to a missing subcommand, a misplaced subcommand-only flag, or an unknown subcommand name each fail structured (exit 2) instead of degrading to help + exit 0.

(cmd *cobra.Command, args []string)

Source from the content-addressed store, hash-verified

366// subcommand, a misplaced subcommand-only flag, or an unknown subcommand name
367// each fail structured (exit 2) instead of degrading to help + exit 0.
368func unknownSubcommandRunE(cmd *cobra.Command, args []string) error {
369 if len(args) == 0 {
370 // A bare group (e.g. `sheets`), or one carrying only group-valid flags
371 // like the global --profile, legitimately prints help. But a flag that
372 // belongs to a (missing) subcommand is a user error: the guard's
373 // FParseErrWhitelist swallows such flags and leaves args empty, so without
374 // the checks below they would silently fall through to help + exit 0 —
375 // letting an agent mistake a malformed call (`im --format json`,
376 // `sheets --badflag`) for success. Recover the swallowed tokens from the
377 // raw invocation and fail structured instead.
378 flags := flagTokensInArgs(rawInvocationArgs)
379 if len(flags) == 0 {
380 return cmd.Help()
381 }
382 if unknown := unknownFlagTokens(cmd, rawInvocationArgs); len(unknown) > 0 {
383 verr := errs.NewValidationError(errs.SubtypeInvalidArgument,
384 "unknown flag %s before a subcommand for %q", strings.Join(unknown, ", "), cmd.CommandPath()).
385 WithHint("flags belong to a subcommand; run `%s --help` to list subcommands and their flags", cmd.CommandPath())
386 for _, flag := range unknown {
387 verr.WithParams(errs.InvalidParam{Name: flag, Reason: "unknown flag before a subcommand"})
388 }
389 return verr
390 }
391 // The remaining flags are all defined somewhere in the tree. Those valid
392 // on the group itself or inherited (e.g. the global --profile) do not
393 // require a subcommand, so a bare group carrying only those still prints
394 // help. Anything left belongs to a subcommand that was omitted
395 // (e.g. `im --format json`): distinct from unknown_flag — the flags are
396 // real, the subcommand is what's missing.
397 misplaced := subcommandOnlyFlagTokens(cmd, rawInvocationArgs)
398 if len(misplaced) == 0 {
399 return cmd.Help()
400 }
401 verr := errs.NewValidationError(errs.SubtypeInvalidArgument,
402 "missing subcommand for %q; flag %s belongs to a subcommand, not the group", cmd.CommandPath(), strings.Join(misplaced, ", ")).
403 WithHint("run `%s --help` to list subcommands and their flags", cmd.CommandPath())
404 for _, flag := range misplaced {
405 verr.WithParams(errs.InvalidParam{Name: flag, Reason: "flag belongs to a subcommand, not the group"})
406 }
407 return verr
408 }
409 unknown := args[0]
410 available, deprecated := availableSubcommandNames(cmd)
411 // Rank suggestions across both current and deprecated names so a mistyped
412 // legacy command (e.g. +raed → +read) still resolves; the alias stays
413 // runnable and self-flags via the _notice on execution.
414 suggestions := suggest.Closest(unknown, append(append([]string{}, available...), deprecated...), 6)
415 msg := fmt.Sprintf("unknown subcommand %q for %q", unknown, cmd.CommandPath())
416 hint := fmt.Sprintf("run `%s --help` to see available subcommands", cmd.CommandPath())
417 if len(suggestions) > 0 {
418 hint = fmt.Sprintf("did you mean one of: %s? (run `%s --help` for the full list)",
419 strings.Join(suggestions, ", "), cmd.CommandPath())
420 }
421 // Record the offending subcommand and its ranked candidates as a param with
422 // machine-readable Suggestions so an agent can retry without parsing the
423 // hint; the hint carries the same candidates as prose.
424 return errs.NewValidationError(errs.SubtypeInvalidArgument, "%s", msg).
425 WithParams(errs.InvalidParam{Name: unknown, Reason: "unknown subcommand", Suggestions: suggestions}).

Calls 9

NewValidationErrorFunction · 0.92
ClosestFunction · 0.92
flagTokensInArgsFunction · 0.85
unknownFlagTokensFunction · 0.85
subcommandOnlyFlagTokensFunction · 0.85
availableSubcommandNamesFunction · 0.85
CommandPathMethod · 0.80
WithParamsMethod · 0.80
WithHintMethod · 0.45