Skip to content

Describing menus

Daniel Frantík edited this page Oct 16, 2026 · 2 revisions

Describing menus

🆕 New in 5.0.

DescribeMenu asks the router itself what a menu offers: its sub-menus and commands, the arguments each command takes, the fields that can be read or cleared, the words an argument accepts, and the router's own help text. Use it to check what this router accepts before you send something — across RouterOS versions, packages and hardware the answers differ.

using tik4net;

TikMenuSchema filter = connection.DescribeMenu("/ip/firewall/filter");

var actions  = filter.ValuesOf("action", "add");        // accept, drop, jump, …
bool ordered = filter.IsOrdered == true;                 // the menu has 'move'
bool hasTable = connection.DescribeMenu("/ip/route").SetArguments?.Contains("routing-table") == true;

With an entity class: connection.DescribeMenu<IpRoute>() (using tik4net.Objects;).

What it answers

Member Answers
Commands, Submenus the commands and sub-menus of the menu
Arguments(verb), AddArguments, SetArguments the argument names a command takes — a name missing here is one the router refuses; null for a command the menu does not have
ReadableFields the fields get takes — the ones a filter can use; null when the menu has no get
UnsetFields the fields that can be cleared; null when the menu has no unset
ValuesOf(argument, verb) the words an argument accepts (enum values, interface names, …) — always asked live
IsOrdered whether the menu has move — rule order is part of the configuration
Description(word, verb) the router's help text for a command or argument; null where it has none
ValueGrammar(argument, verb) the router's definition of a value, e.g. Num ::= 1..255 (integer number)
Source where the answer came from (see below)
var route = connection.DescribeMenu("/ip/route");
string? help = route.Description("distance", "add");      // "Administrative distance of the route"
var ping = connection.DescribeMenu("/tool").Arguments("ping");   // address, count, interface, …

Where the answer comes from

Transport RouterOS 7 RouterOS 6
Api, ApiSsl, Rest, RestSsl /console/inspect not available — throws TikNoSuchCommandException
CLI transports /console/inspect Tab completion and the F1 help
WinBox native the router's .jg catalog the router's .jg catalog
  • WinBox native knows a window's fields, not the menu tree: Commands is empty, Submenus, IsOrdered and UnsetFields are null, and there is no Description or ValueGrammar. Prefer DescribeMenu<TEntity>() there — the field names then match the API's.
  • Each menu is asked once per connection. The CLI transports also keep the grammar on disk under CatalogCachePath, per RouterOS build, so the next connection to the same build does not ask again — useful on RouterOS 6, where Tab completion is slow.
  • A menu the router does not have throws TikNoSuchCommandException; a transport without the MenuSchema capability throws TikConnectionCapabilityNotSupportedException.

Validating writes

Set ValidateWrites and every entity write is checked against the router's argument list before it is sent:

var setup = new TikConnectionSetup(HOST, USER, PASS) { ValidateWrites = true };
  • A field the router knows under another name (a field renamed between RouterOS versions) is sent under the name the router takes.
  • A field the router does not take, or cannot clear, throws TikUnknownFieldException naming it — and nothing is sent.
  • SaveListDifferences checks the whole list before its first write, so a list is never left half-applied.
  • Entity writes only (Save, SaveListDifferences); a command you build yourself is sent as written.
  • Skipped on WinBox native (it refuses unknown fields anyway) and where the router cannot describe the menu (RouterOS 6 over the API). Costs one extra request on the first write to each menu.

See also

Clone this wiki locally