Common errors¶
Amri checks a profile when it loads. If anything is wrong, it refuses the whole profile and prints each problem, so a broken command cannot silently do nothing. The report looks like this:
The name in brackets is the command the error came from. This page lists the errors you are most likely to see, why each happens, and how to fix it.
Keys written after a subtable header¶
The most common mistake. In TOML, every key you write after a [command.xxx]
header belongs to that subtable, not to the command. So a lua or script key
placed below [command.trigger] attaches to the trigger, where it does nothing.
Amri catches this specific case and stops:
command 'open_map': stray 'lua' key found inside [command.trigger] —
move it to the [[command]] level (sibling of `name`), before the
[command.trigger] section header.
The fix is ordering. Put every command-level key (name, description,
lua, script, response, confidence) above the [command.trigger]
header. The subtable comes last.
# Wrong: lua binds to the trigger, not the command
[[command]]
name = "open_map"
[command.trigger]
pattern = "open the map"
lua = "amri.input.tap('m')"
# Right: command-level keys first, subtable last
[[command]]
name = "open_map"
lua = "amri.input.tap('m')"
[command.trigger]
pattern = "open the map"
Why only lua and script are caught
[command.trigger] has a fixed set of keys, so a stray lua there is
unambiguous. Tables like [command.variables] accept any key you invent, so
a misplaced key there cannot be told apart from a variable you meant to
define. When a value seems ignored, check what header sits above it.
A command with no action¶
Every command needs something to do. Give it exactly one of response (a
keystroke string), script (a Lua file), or lua (inline Lua).
See Triggers for the trigger half of a command.
More than one action¶
A command runs one body. Pick a single one of response, script, or lua and
remove the others.
A pattern that expands to nothing¶
Every part of a pattern was optional, so one expansion produced an empty spoken phrase. That would trigger on silence, so it is rejected. At least one segment must be required.
# Wrong: both segments optional, so "" is a valid phrase
pattern = "[jump;hyperspace;] [jump;engage;]"
# Right: a required word anchors the phrase
pattern = "engage [jump;hyperspace;]"
The same phrase twice¶
A pattern that produces the identical spoken phrase by two different paths is rejected. This catches both an accidental repeat and a genuinely ambiguous pattern where one phrase could fill a capture two ways.
# Wrong: two optional [fast;] segments both expand to "engage fast"
pattern = "engage [fast;] [fast;]"
Remove the duplicated segment so no two paths land on the same words. The check compares phrase text only.
Two commands that hear the same phrase¶
Two separate commands expanded to the same spoken phrase, so Amri cannot tell which one you meant. Change one command's pattern, or use synonyms so each phrase belongs to a single command.
Too many phrases (permutation budget)¶
Each command may expand to at most 10,000 phrases. Stacking large captures multiplies fast, and past the cap the command is rejected:
# 101 x 100 = 10,100 phrases, past the cap and almost always a mistake
pattern = "{x:1..101} {y:1..100}"
Narrow the number ranges, or split one command into several smaller ones. A command that crosses 1,000 phrases (well under the cap) draws a warning that suggests simplifying, but still loads.
Warnings versus errors¶
Errors block the profile. Warnings do not: the profile still loads, but Amri
prints the note so you can review it. Common warnings include a capture
reached on only some phrasings, a variable that shadows a wider one, and a Lua
hold with no matching release. Read them even when things work.