Errors

The complete error catalog: schema errors (your code is wrong), driver errors (the run's outcome), and the runtime parse-error kinds. For how these look and how to handle them, see Errors & Diagnostics.

DriverError

The outcome of Driver::run(). Variants, exit codes, and whether they mean success:

VariantexitsuccessWhen
Help { text, suggestion }0--help, or guided help when only a subcommand / required CLI arg is missing
HtmlHelp { path }0--html-help wrote a page (browser opens on .unwrap())
Completions { script }0--completions <shell>
Version { text }0--version
JsonSchemasExported { paths }0--export-jsonschemas <dir>
Failed { report }1parse / type / missing / conflict error
Builder { error }1invalid schema — see BuilderError
JsonSchemaExport { error }1could not write schema files
EnvSubst { error }1${VAR} undefined with no default
HtmlHelpFailed { error }1could not write/open HTML help

Helpers: exit_code() -> i32, is_success() -> bool, is_help() -> bool (matches Help only, not HtmlHelp), help_text() -> Option<&str>. Implements std::process::Termination.

BuilderError

Returned by builder::<T>() / wrapped in DriverError::Builder. Setup-phase failures: SchemaError, Alloc, FileNotFound, FileRead, FileParse, CliParse, UnknownKey { key, source, suggestion }, MissingRequired. The common one is SchemaError.

SchemaError

Raised before any parsing when the type itself is not a valid figue target. Rendered with ariadne, pointing at the offending field (the "defined at file:line" label needs facet's doc feature). Fix it once and never see it again. The full catalog:

MessageTrigger
top-level shape must be a structroot type T is an enum / not a struct
field \x` is missing a #[facet(args::...)] annotation`a plain field with no role and no flatten/config
field \x` uses args::env_prefix without args::config`env_prefix on a non-config field
flattened field \x` must be a struct`#[facet(flatten)] on a non-struct
struct fields in args must use #[facet(flatten)]a struct-typed arg field that isn't flattened or a config root
config field must be a structargs::config on a non-struct
flattened config field \x` must be a struct`flatten inside a config struct on a non-struct
#[facet(args::positional)] is not compatible with #[facet(args::short)]both on one field
field \x` marked as counted must be an integer`args::counted on a non-integer (incl. bool)
field \x` marked as subcommand must be an enum`args::subcommand on a non-enum
only one field may be marked with #[facet(args::subcommand)] at this leveltwo subcommand fields (incl. via flatten)
#[facet(args::config)] inside a subcommand variant is not supporteda config field within a subcommand variant
duplicate flag \--x`/duplicate flag `-x``two args resolve to the same long/short flag
duplicate argument \x``two args share an effective name
duplicate subcommand name \x``two variants resolve to the same CLI name
duplicate subcommand short alias \x``two variants share an args::short
subcommand short alias \x` conflicts with existing subcommand name`alias equals another subcommand's name
env alias \x` is used by both `a` and `b``two fields share an args::env_alias

(Several of the duplicate messages have "(from flattened field)" / "(from flattened config root)" variants when the collision is introduced by a #[facet(flatten)].)

Note: a subcommand short alias and a flag short of the same letter do not conflict — they live in separate namespaces.

A rendered example:

text
Error: field `foo` is missing a #[facet(args::...)] annotation
   ╭─[ <schema>:3:5 ]
   │
 2 │ struct MissingArgsAnnotation {
   │        ──────────┬──────────
   │                  ╰──────────── defined at src/main.rs:65
 3 │     foo: String,
   │     ─────┬─────
   │          ╰─────── field `foo` is missing a #[facet(args::...)] annotation
 4 │ }
───╯

Runtime error kinds (ArgsErrorKind)

When a Failed report is produced, the underlying parse problem is one of (#[non_exhaustive]):

Kindcode()Typical message / help
UnknownLongFlagargs::unknown_long_flagunknown flag --x · did you mean --y?
UnknownShortFlagargs::unknown_short_flagunknown flag -x (precise char span in clusters)
MissingArgumentargs::missing_argumentmissing required argument --x · provide a value with --x <T>
ExpectedValueGotEofargs::expected_valueexpected <T> value · provide a value after the flag
UnexpectedPositionalArgumentargs::unexpected_positionallists available options / hints a missing args::subcommand
UnknownSubcommandargs::unknown_subcommandunknown subcommand x · did you mean y?
MissingSubcommandargs::missing_subcommandexpected a subcommand · lists available
NoFieldsargs::no_fieldstype has nothing to parse into
EnumWithoutSubcommandAttributeargs::enum_without_subcommand_attributeenum field needs #[facet(args::subcommand)]
MissingArgsAnnotationargs::missing_args_annotation(also surfaces as a schema error)
ReflectErrorargs::reflect_errortype/parse failures, e.g. failed to parse "abc" as u16 at config.port
Help / Version / Completions Requestedargs::help etc.the success exits

Type/parse failures (ReflectError) carry a span that the driver maps back — through a span registry — to the original CLI token, the synthetic <env> line, or the real config-file location, so the underline always points at what the user actually wrote.

Suggestions

"Did you mean …?" uses Jaro–Winkler similarity (threshold ≈ 0.8, case-insensitive) for flags, subcommands, and config-override paths (the config path suggester walks the schema segment by segment to find the first wrong segment).

Color and snapshots

Diagnostics are colored when supported; NO_COLOR / FORCE_COLOR are honored, and color is force-disabled when any INSTA_* env var is set so snapshot tests stay stable. There is no separate "plain vs rich" mode — the ariadne layout is always produced, only color toggles.