Skip to content
Version v0.35 · supported
[WIP] Pending copyedit and approval.

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:

Profile validation failed:
  - Command "open_map" has no action defined. Set one of: ... [open_map]

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

Command "open_map" has no action defined. Set one of: ...

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

Command "open_map" has more than one of response/script/lua (mutually exclusive)

A command runs one body. Pick a single one of response, script, or lua and remove the others.

A pattern that expands to nothing

Command "warp" expansion error: Pattern produces an empty phrase

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.

Command "engage" expansion error: Duplicate phrase: "engage fast"
# 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

Ambiguous phrase "reload" matches both "reload_weapon" and "reload_profile"

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:

Command "grid" expansion error: Permutation limit (10000) exceeded
# 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.