List Names
When you name a list on the command line, as in ritual price burn or ritual edit "Winota Stax", every command matches that name the same way. This page describes the rules.
How a name is matched
Section titled “How a name is matched”Ritual searches the existing list files and applies these rules in order:
- Byte-exact match. A list whose file name equals the input character for character wins outright. Only a trailing
.mdand surrounding whitespace are removed first. Typing a name exactly always selects that one list. - Exact match under folding. Case, diacritics, separators, and punctuation are ignored (see the table below). A list whose file name equals the input under those rules wins next.
- Unique substring match. If nothing matches exactly, a list whose name contains the input (under the same folding) is accepted, but only if exactly one does.
- Otherwise it is an error. No match is a “not found” error. More than one match at the winning tier is an “ambiguous” error.
Matching is against the file name without its .md extension, not the # Title heading or the front matter.
What folding ignores
Section titled “What folding ignores”Tiers 2 and 3 compare the query and each file name in a folded form. Exactly these things are ignored:
| Folded | Example |
|---|---|
| Case | goblins resolves Goblins.md |
| Accents and other diacritics | cafe resolves Café.md, and Café resolves cafe.md |
| Hyphens and underscores (treated as spaces) | winota-stax resolves Winota Stax.md |
| Repeated whitespace, and leading/trailing space | mono red resolves Mono Red.md |
Apostrophes ', ’, `, ʼ |
Praetors Voice resolves Praetors' Voice.md |
Characters a file name cannot hold: / \ : * ? " < > | |
Atraxa: Praetors' Voice resolves Atraxa Praetors' Voice.md |
| Everything else the file namer changes: runs of dots collapse to one, leading and trailing dots are dropped | Mono-U Tron... Redux resolves Mono-U Tron. Redux.md |
The last two rows make a display name round-trip. A list created as Atraxa: Praetors' Voice is stored as Atraxa Praetors' Voice.md, because a colon cannot be in a file name, and the name you typed at creation still finds it. Resolution folds the query through the same function the file namer uses, so the two never disagree.
Two lists whose names differ only in folded characters (Mono Red and mono-red, or AB.md beside A'B.md) are ambiguous at tiers 2 and 3. Each is still reachable by tier 1: type its full name exactly as the file spells it. Ritual refuses to create the second name of such a pair, so one can exist only in an older workspace. rename moves one of them out of the way.
Names that would collide are refused at creation
Section titled “Names that would collide are refused at creation”Folding makes Atraxa Superfriends and atraxa superfriends the same name, so new and rename refuse a name that folds onto an existing list of the same type:
A deck named 'Atraxa Superfriends' already exists (it matches 'atraxa superfriends' under list-name folding).The refusal is a usage error (exit 2; HTTP 409 on the admin API) and names the existing list. Renaming a list to a different spelling of its own name (fixing capitalization, dropping a colon) is allowed.
The same rule applies wherever a list is created: the CLI, the interactive editor’s in-session list creation (including a list created earlier in the same unsaved session), cleanup’s renames, the importers, the admin site, the MCP create_list/rename_list tools, and collection sync.
Type flags and disambiguation
Section titled “Type flags and disambiguation”Most commands search all three list types at once: add-card, remove-card, set-card, note, edit, history, price, sell, export, rename, and delete. A name that exists in more than one type (a deck and a collection both called staples) is ambiguous. Resolve it with a type flag:
| Flag | Restricts the search to |
|---|---|
--deck |
Decks |
--collection |
Collections |
--wanted |
Wanted lists |
The flags are mutually exclusive. A deck:/collection:/wanted: prefix on the name itself (collection:staples) selects the type too, and supplies it when no flag is given. A prefix that contradicts the flag is a usage error (exit 2) naming both:
ritual delete deck:"Trade Binder" --collection# 'deck:Trade Binder' selects a deck, which conflicts with --collection.# Drop the 'deck:' prefix or the --collection flag.Commands that take more than one list cannot scope each argument with one whole-command flag, so their ambiguity errors suggest the prefix. That covers diff’s two sides, move’s --from/--to, and the list arguments of export and sell. lists does not resolve a name, but accepts the same three flags to filter which types it enumerates.
Single-type commands (deck-sync, collection-sync, get-primer, and the CSV importer) already know their type, so they take no flag. They match names by the same folding, substring, and ambiguity rules. Their ambiguity errors never suggest a type selector: they use the first row of the table below, or the second when the matching names fold together.
What the ambiguity error advises
Section titled “What the ambiguity error advises”The error always lists every match. The remedy line under it names the mechanism the command you ran actually has:
| Situation | Advice |
|---|---|
| All matches are the same type (including single-type commands) | Type more of the name to narrow the match (e.g. 'burn'). |
| Matches that fold together but differ byte-wise | Type one list's exact full name, spelled and capitalized as its file is (e.g. 'Atraxa Superfriends'). |
| Matches span types, command takes type flags | Disambiguate with --deck, --collection, or --wanted. |
Matches span types, the name takes a type prefix (move, diff, export, sell) |
Disambiguate with a type prefix, e.g. 'deck:Storm' or 'wanted:Storm'. |
Matches span types, the caller sends a structured type field (POST /api/export) |
Set the list's type to 'deck' or 'wanted'. |
| Matches span types, no type selector exists at all | Type more of the name to narrow the match (e.g. 'Storm'). |
A type selector cannot break a tie between two lists of the same type, so the same-type case always asks for a longer name. A type is only suggested when it holds exactly one match. When no type qualifies, the error asks for a longer name instead.
The suggested example name always resolves. When two files fold to the same name (Storm Crow.md and storm-crow.md), a longer name would not help, so the advice asks for one list’s exact full name, which the byte-exact tier honors. Only when the matches are byte-identical (the same file name under two list types) is no example offered, because no name can break that tie.
Examples
Section titled “Examples”# Exact, case- and accent-insensitive — resolves decks/Goblins.mdritual price goblins --deck
# Unique substring — resolves decks/mono-red-burn.mdritual price burn --deck
# Ambiguous across types — fails, asking you to disambiguateritual note staples "Sol Ring" --note ramp# 'staples' is ambiguous — it matches multiple lists:# - Deck: staples# - Collection: staples# Disambiguate with --deck, --collection, or --wanted.
# Disambiguated with a flagritual note --collection staples "Sol Ring" --note ramp
# Ambiguous within one type — no flag can help, so type more of the nameritual edit bur# 'bur' is ambiguous — it matches multiple lists:# - Deck: burn# - Deck: burn-red# Type more of the name to narrow the match (e.g. 'burn').
# Two decks that fold together — each is still reachable, exactly as spelledritual edit "atraxa superfriends" # resolves decks/atraxa superfriends.mdritual edit "Atraxa Superfriends" # resolves decks/Atraxa Superfriends.md
# The display name round-trips, colon and allritual delete "Atraxa: Praetors' Voice" --confirm "Atraxa: Praetors' Voice"Ritual is unofficial Fan Content permitted under the Fan Content Policy. Not approved or endorsed by Wizards of the Coast. Portions of the materials used are property of Wizards of the Coast. ©Wizards of the Coast LLC.
Card data, images and symbols come from Scryfall, which is not affiliated with this project. Ritual is free software under the AGPL-3.0. License and attribution.