Skip to content

Error Codes ​

Every FLAP method that can fail accepts an optional error integer argument, and prints its message on the error unit (standard error unless init(error_lun=...)). FLAP never stops the program on an error: the program decides.

fortran
call cli%parse(error=error)
if (error /= 0) stop 1, quiet=.true.   ! the message is already printed; nvfortran: call exit(1)

Code table ​

Every code is available as a named constant from the flap module, so programs can test for a specific condition without hard-coding numbers:

fortran
use flap, only : command_line_interface, ERROR_UNKNOWN, STATUS_PRINT_H

Negative values are statuses (FLAP did what was asked and the program should usually exit cleanly); positive values are errors. Existing values never change.

CodeConstantMeaningTypical causeClass
-10STATUS_CHECKCommand line valid--check was passed (init(check_option=.true.)) and the command line is valid; in standalone mode the program ends with exit status 0
-9STATUS_SCHEMAJSON description printed--schema was passed (init(schema_option=.true.)); in standalone mode the program ends with exit status 0
-8STATUS_PRINT_MANMan page saved--man was passed (init(man_option=.true.)); in standalone mode the program ends with exit status 0
-7STATUS_INSTALL_COMPLETIONCompletion script installed--install-completion was passed (init(completion_options=.true.)); in standalone mode the program ends with exit status 0
-6STATUS_SHOW_COMPLETIONCompletion script printed--show-completion was passed; in standalone mode the program ends with exit status 0
-5STATUS_NO_ARGSHelp printed, no argumentsinit(no_args_is_help=.true.) and no argument passed (or a command with no_args_is_help invoked alone); in standalone mode the program ends with exit status 2
-4STATUS_ALTERNATEAn alternate action was passedAn option with act='alternate' (e.g. --list-models): value validation skipped, dispatch on is_passed; returned also in standalone mode
-3STATUS_PRINT_MHelp written as Markdown--markdown was passed; not a real error
-2STATUS_PRINT_HHelp printed--help / -h was passed; not a real error
-1STATUS_PRINT_VVersion printed--version / -v was passed; not a real error
0SuccessNo error
1ERROR_OPTIONAL_NO_DEFMissing default for optional argumentAdded required=.false. but omitted def=definition
2ERROR_REQUIRED_M_EXCLUDERequired argument cannot use excluderequired=.true. combined with exclude=definition
3ERROR_POSITIONAL_M_EXCLUDEPositional argument cannot use excludepositional=.true. combined with exclude=definition
4ERROR_NAMED_NO_NAMENamed argument has no switchNon-positional add called without switch=definition
5ERROR_POSITIONAL_NO_POSITIONPositional argument has no positionpositional=.true. without position=definition
6ERROR_POSITIONAL_NO_STOREPositional argument must use act='store'Incompatible action for a positional CLAdefinition
7ERROR_NOT_IN_CHOICESValue not in choices listUser supplied a value outside the allowed setusage
8ERROR_MISSING_REQUIREDRequired argument missingA required=.true. argument was not passedusage
9ERROR_M_EXCLUDETwo mutually exclusive arguments both passedBoth sides of an exclude= pair were givenusage
10ERROR_CASTING_LOGICALCast to logical failedCLA value string cannot be parsed as logicalusage
11ERROR_CHOICES_LOGICALchoices not allowed for logical typechoices= used with a boolean argumentdefinition
12ERROR_NO_LISTArgument is not list-valuedget used with an array on a scalar argumentdefinition
13ERROR_NARGS_INSUFFICIENTInsufficient list argumentsnargs='N' but fewer than N values were passedusage
14ERROR_VALUE_MISSINGMissing valueA named argument was passed but no value followedusage
15ERROR_UNKNOWNUnknown switchAn unrecognised switch (or argument) was passed on the command line; the message suggests the closest names (see Did you mean)usage
16ERROR_ENVVAR_POSITIONALenvvar not allowed for positionalenvvar= combined with positional=.true.definition
17ERROR_ENVVAR_NOT_STOREenvvar requires act='store', store_true or store_falseEnvironment variable used with an incompatible action (store*, count, append, ...)definition
18ERROR_ENVVAR_NARGSenvvar not allowed for list-valuedNo longer raised: lists accept an envvar (comma-separated values)definition
19ERROR_STORE_STAR_POSITIONALact='store*' not allowed for positionalIncompatible combinationdefinition
20ERROR_STORE_STAR_NARGSact='store*' not allowed for list-valuedIncompatible combinationdefinition
21ERROR_STORE_STAR_ENVVARact='store*' not allowed with envvarIncompatible combinationdefinition
22ERROR_ACTION_UNKNOWNUnknown actionact= set to an unrecognised stringdefinition
23ERROR_DUPLICATED_CLASArgument passed more than onceThe same switch appears twice on the command lineusage
24ERROR_MISSING_REQUIRED_VALRequired value not passedA switch that needs a value got noneusage
25ERROR_INLINE_VALUE_NOT_ALLOWEDInline value for a flag--flag=yes on an option that takes no valueusage
26ERROR_INLINE_VALUE_NARGSInline value for a list--list=1 on an option with nargs: pass the values after the switchusage
27ERROR_COUNT_INCONSISTENTInvalid countA count option that is positional or has nargs, envvar or choicesdefinition
28ERROR_APPEND_INCONSISTENTInvalid appendAn append option that is positional or has nargs or envvardefinition
29ERROR_APPEND_SCALAR_GETScalar get of an appendAn append option holds a list: read it with get_varying or into an arraydefinition
30ERROR_RANGE_DEFINITIONInvalid rangeA non-numeric bound, min > max, an empty open interval, a range on a flag; or get of a real that would clamp to an open bounddefinition
31ERROR_OUT_OF_RANGEValue out of rangeget of a value outside min/max (without clamp)usage
32ERROR_RANGE_TYPERange on a non-numeric getget into a character or logical of an option with a rangedefinition
33ERROR_PATH_NOT_FOUNDPath does not existmust_exist=/readable= and the file is missingenvironment
34ERROR_PATH_NOT_READABLEPath not readablereadable= and the file cannot be opened for reading (the message gives the reason)environment
35ERROR_PATH_NOT_WRITABLEPath not writablewritable= and the existing file cannot be opened for writingenvironment
36ERROR_SWITCH_NEG_INCONSISTENTInvalid flag negationswitch_neg= on an argument that is not a named store_true/store_false flag without nargs, blank, or equal to its own switch namesdefinition
37ERROR_ALTERNATE_INCONSISTENTInvalid alternate actionact='alternate' with nargs, envvar, choices, exclude, required=.true. or positionaldefinition
38ERROR_MAP_FORMATMap item not KEY=VALUEA map pair without = or with an empty key (command line, environment, configuration or default)usage
39ERROR_MAP_DUPLICATE_KEYMap key repeatedThe same key twice in a mapusage
40ERROR_MAP_UNKNOWN_KEYMap key not allowedA key outside map_keys; the message lists the allowed keys and suggests the closestusage
41ERROR_MAP_KEY_MISSINGMap key not givenget_map_value of a missing key without found=usage
42ERROR_MAP_INCONSISTENTInvalid mapmap=.true. on a positional, a flag, a scalar store or with choices; map_keys without map; get_map of an option that is not a mapdefinition
43ERROR_ENVVAR_CSVUnterminated quote in a list from the environmentWORKERS='1,"99' for an option with nargs and envvar='WORKERS'environment
44ERROR_DEPRECATED_REQUIREDA required option cannot be deprecateddeprecated= combined with required=.true.definition
45ERROR_POSITIONAL_NARGSnargs on a positional argumentPositionals take one value each: use a named list optiondefinition
46ERROR_UNSUPPORTED_TYPEUnsupported variable typeget into a type FLAP cannot fill (e.g. complex, or a non-logical for a flag)definition
47ERROR_LIST_SIZEList size differs from the array sizeget into a fixed-size array with more or fewer elements than the values: use an array of the right size, or get_varyingusage
48ERROR_DEF_NARGSDefault count differs from nargsnargs='N' with a default of another number of values: give the default N valuesdefinition
49ERROR_PATH_INCONSISTENTPath checks on an option without valuemust_exist/readable/writable/allow_dash on a flag, count, ...definition
50ERROR_CASTING_NUMBERValue is not a numberget into an integer or a real of a value that is not exactly one number (--nx many, --nx /, --nx 2*5), from any source, or parse of an option with val_type; the message names the value, the option and the typeusage
51ERROR_TYPE_DEFINITIONInvalid val_typeAn unknown name; a map, a configuration file option or an action without value; a flag not logical, a count not an integer, a path not character; a range on a non-number; a default or a choice that does not fit the typedefinition
52ERROR_TYPE_MISMATCHget against val_typeget into another family or a narrower kind than declared, whatever the value (character is always allowed)definition
100ERROR_GROUP_CONSISTENCYGroup (command) consistency brokenTwo arguments of a group share a switchdefinition
101ERROR_GROUP_M_EXCLUDETwo mutually exclusive groups both passedBoth sides of set_mutually_exclusive_groups givenusage
102ERROR_M_EXCLUDE_SETTwo members of a mutually exclusive set passed--mesh m --restart r with set_mutually_exclusive_switches(switches='--mesh,--restart')usage
103ERROR_M_EXCLUDE_SET_REQUIREDNo member of a required set passedNone of the switches of a set with required=.true. givenusage
104ERROR_M_EXCLUDE_SET_DEFINITIONInvalid mutually exclusive setFewer than two switches, an undefined, repeated or required member, or a switch already in a set (returned by set_mutually_exclusive_switches, then by parse)definition
105ERROR_POSITION_DUPLICATEPosition declared twiceTwo positionals of a group (command) with the same position (raised by add)definition
106ERROR_POSITION_GAPMissing positionPositions are not 1..N, e.g. 1 and 3 without 2 (raised when parsing starts)definition
1000ERROR_MISSING_CLAArgument not found in CLIget or get_source called for an undefined switch (is_passed returns .false., with no error)definition
1001ERROR_MISSING_GROUPGroup not found in CLIget, get_source or set_mutually_exclusive_groups called for an undefined group (run_command returns .false., with no error)definition
1002ERROR_MISSING_SELECTION_CLANo argument selectedget called with neither switch= nor position=definition
1003ERROR_TOO_FEW_CLASInsufficient arguments for CLIReserved: not raised by the current versionusage
1004ERROR_UNKNOWN_CLAS_IGNOREDUnknown arguments ignoredinit(ignore_unknown_clas=.true.) and an unknown switch was passed: not printed, the message of one of them is in cli%error_messageusage
1005ERROR_USERApplication errorReturned by cli%raise_error (see below)application
1006ERROR_CONFIG_NOT_FOUNDConfiguration file not foundset_config(file=..., required=.true.) and the file is missing (or cannot be read)environment
1007ERROR_CONFIG_UNKNOWN_KEYConfiguration file: unknown keyAn unknown key or section, a key of an option taking no value, or a malformed line (the message names the line)environment
1008ERROR_GROUP_ALIASInvalid command aliasadd_group(aliases=...) with an alias equal to a command name or another alias, repeated, blank or equal to its command, or a command name equal to an alias; parse then fails toodefinition
1009ERROR_COPY_POSITIONALPositional in copy_optionscopy_options(switches=...) names a positional argument: only named options are copieddefinition
1010ERROR_COMPLETION_SHELLUnknown completion shell--show-completion/--install-completion with a shell other than bash, zsh, fish, powershell, or none given and $SHELL unset; --install-completion powershell (install it by hand)usage
1011ERROR_COMPLETION_INSTALLCompletion not installed$HOME unset, or the script or the rc file cannot be written (the message carries the I/O error; for fish, ~/.config/fish must exist)environment
1012ERROR_ARGUMENT_RETRIEVALA command line argument cannot be readget_command_argument failed (processor error; not expected in practice)environment
1013ERROR_COMMAND_REPEATEDA command passed more than onceprog commit -m x commit, or a command and one of its aliases; reported before --helpusage
1014ERROR_USAGE_ON_ERRORInvalid usage_on_errorinit(usage_on_error=...) other than full, usage, none (any case); reported by parsedefinition
1015ERROR_FORMATInvalid error_formatinit(error_format=) is not text or jsondefinition
2001ERROR_MENU_INVALIDInvalid menu answerNot one of the numbers shown, an empty field, or unreadable (see Interactive Menus)usage
2002ERROR_MENU_TOO_MANYToo many menu answersSeveral answers to a single-choice menuusage
2003ERROR_MENU_DUPLICATEDuplicate menu answerThe same option chosen twice with multiple selectionusage
2004ERROR_MENU_NO_RESPONSEEmpty menu answerThe user just pressed Enter, and the menu has no default optionusage
2005ERROR_MENU_EOFEnd of input in a menuStandard input at its end (/dev/null, a batch job): no answer can comeenvironment
2006ERROR_MENU_DEFINITIONInvalid menurun on a menu without options, add_option with an empty text or a second default (single choice), init(tries=) below 1 or init(separator=''), the scalar run(choice) on a menu with multiple selection, yes_no(default=) other than y or ndefinition

The first two group codes are named ERROR_GROUP_* in the flap module; inside the group module they are ERROR_CONSISTENCY and ERROR_M_EXCLUDE, which would clash with the argument-level ERROR_M_EXCLUDE (9).

Exit statuses ​

The class of an error says what must change before trying again, and cli%exit_status() turns it into an exit status. FLAP does not end the program on an error, except with --check: the program writes stop cli%exit_status().

Exit statusClassWhat to changeConstant
0Nothing: success, a status, or an unknown argument the program asked to ignore
1applicationLeft to the program: raise_error, and its own failuresEXIT_APPLICATION
2usageThe command line; also STATUS_NO_ARGSEXIT_USAGE
3environmentA file or a variable: the command line may be rightEXIT_ENVIRONMENT
4definitionThe program: retrying cannot helpEXIT_DEFINITION

error_class(code) (a string, '' for a status or an unknown code) and error_exit_status(code) (an integer) give the same answers for any code, error_description(code) the meaning of the table above, and JSON errors carry "class". The class belongs to the code, not to where the value came from: a bad number from a configuration file is still usage.

Handling status codes ​

Negative codes mean that FLAP did what the user asked (printed the help, saved the man page, ...). By default parse ends the program itself right after, with exit status 0 (2 for STATUS_NO_ARGS), so these statuses are not returned to your code; STATUS_ALTERNATE is always returned. With init(standalone=.false.) parse returns every status instead: the program can clean up first (close files, call MPI_Finalize), and the help can be tested in-process.

f90
call cli%init(progname='statuses', version='v2.4.0', standalone=.false., no_args_is_help=.true.)
f90
call cli%parse(error=error)
select case(error)
case(0)
  print '(A)', 'running'
case(STATUS_PRINT_H, STATUS_PRINT_V, STATUS_PRINT_M)
  print '(A)', 'help, version or Markdown printed: cleaning up, then exit status 0'
case(STATUS_NO_ARGS)
  stop 2, quiet=.true.
case default
  stop 1, quiet=.true.
endselect
$ statuses --help
usage: statuses [--mesh value] [--help] [--markdown] [--version]

Optional switches:
  --mesh value
      default value m.grd
      Mesh file
  --help, -h
      Print this help message
  --markdown, -md
      Save this help message in a Markdown file
  --version, -v
      Print version
help, version or Markdown printed: cleaning up, then exit status 0

When several of them are passed, one wins, in this order (--schema comes between the man page and completion): a syntax error anywhere on the command line (an unknown or duplicated switch, a missing value, a repeated command) is returned first, then help, version, Markdown, man page and completion. --version --help prints the help; --help compile --bogus reports the unknown switch.

Reporting application errors ​

Checks that only your program can do (--nx must be even, --t-end must exceed --t-start) can be reported in FLAP's own style (program name, error colour, error unit) with raise_error:

fortran
call cli%get(switch='--nx', val=nx, error=error)
if (mod(nx, 2) /= 0) error = cli%raise_error('must be even', switch='--nx')
if (error /= 0) stop 1
f90
call cli%get(switch='--nx', val=nx, error=error)
if (mod(nx, 2) /= 0) error = cli%raise_error('must be even', switch='--nx')
if (error /= 0) stop 1, quiet=.true.
$ raise_error --nx 33
raise_error: error: switch "--nx": must be even

usage: raise_error [--nx value] [--help] [--markdown] [--version]
[exit status 1]

It returns ERROR_USER (1005, and sets cli%error) and never stops: the program decides what to do. The help follows the message unless show_usage=.false., as init(usage_on_error=...) chooses (the whole help, the usage line as here, or nothing); with group='post' it is the help of that command (an undefined group returns ERROR_MISSING_GROUP and prints nothing). It works before or after parse.

Error hint ​

After a failed parse FLAP prints one more line to the error unit, pointing to the help (the command is named when the error is inside one):

$ actions --verbse
actions: error: switch "--verbse" is unknown! Did you mean "--verbose"?

Try 'actions --help' for help.
[exit status 1]

It is printed once, as the last line, only when there is a --help to suggest (not with disable_hv=.true.), and never for statuses, ignored unknown arguments or errors raised later by get (a value out of its choices or range). Disable it with init(error_hint=.false.).

Output after an error ​

A missing required option (and a required mutually exclusive set with no member given) prints the whole help of its group (command) after the error message. init(usage_on_error=...) chooses what is printed instead:

ValuePrinted after the error message
'full' (default)the whole help of the group, as before
'usage'the usage line only, the first line of --help
'none'nothing
f90
call cli%init(progname='usage_on_error', usage_on_error='usage')
$ usage_on_error
usage_on_error: error: named option "--mesh" is required!

usage: usage_on_error --mesh value [--cfl value] [--help] [--markdown] [--version]
Try 'usage_on_error --help' for help.
[exit status 1]

With the default 'full' (the minimal program of the Installation page):

$ minimal
minimal: error: named option "--string" is required!

usage: minimal --string value [--help] [--markdown] [--version]

minimal FLAP example

Required switches:
  --string value, -s value
      a string

Optional switches:
  --help, -h
      Print this help message
  --markdown, -md
      Save this help message in a Markdown file
  --version, -v
      Print version
Try 'minimal --help' for help.
[exit status 1]

The error message and the hint line are always printed, and --help always prints the whole help. Any other value is ERROR_USAGE_ON_ERROR (1014), returned by parse.

Did you mean ​

An unknown argument gets up to three suggestions, most similar first, with click's wording:

$ actions --verbse
actions: error: switch "--verbse" is unknown! Did you mean "--verbose"?

Try 'actions --help' for help.
[exit status 1]
$ fake_git comit
fake_git: error: argument "comit" is unknown! Did you mean "commit"?

Try 'fake_git --help' for help.
[exit status 1]

With several candidates the message is (Did you mean one of: "--mass", "--mach"?).

The candidates are the visible switches, abbreviations and negations of the command being parsed (hidden switches never), and, at the top level, for an argument that is not a switch, the command names and aliases. A name is suggested when its similarity 1 - d/max(len) is at least 0.6, d being the Levenshtein (edit) distance; in any case with init(case_insensitive=.true.). The name of --name=value is the part before =.

Accessing the error message ​

command_line_interface has a public error_message attribute that contains a human-readable description of the last error, the text FLAP prints on the error unit, whichever part of the CLI raised it (parse, get, add, ...). It is allocated only when cli%error is an error: not after a call that succeeds, nor after a status (the help printed, ...). Check the error before reading it:

fortran
call cli%parse(error=error)
if (error /= 0) then
  write(*,'(A)') trim(cli%error_message)
  stop 1
end if

Released under GPL v3, BSD 2-Clause, BSD 3-Clause or MIT, at your choice.