This document lists every diagnostic code emitted by tx, grouped by prefix.
Codes are part of the public API surface — renaming or removing a code requires
a major version bump (see cli-ux-guidelines.md).
Under --output-format json (or --error-format json), errors are emitted on stderr
as a single JSON object using the first Error/Fatal diagnostic:
{"error":"Human-readable message describing what happened.","code":"TOMIX_MUTATION_FAILED","severity":"Error","hint":"Optional guidance on how to fix the problem."}
Fields:
Field
Type
Description
error
string
The diagnostic message. Always present.
code
string
The diagnostic code (see tables below). Always present.
severity
string
Info, Warning, Error, or Fatal.
hint
string
Optional fix suggestion. May be null.
blocked
boolean
Present as true when a mutation save is blocked by validation.
reason
string
validation for a blocked mutation save.
newValidationErrorCount
integer
Count of errors introduced by the mutation.
newErrors
array
Introduced errors, each with code, message, and object.
objectPath
string
The model object the error is about, when there is one (for example tx format --path).
line, column
integer
1-based position of the first syntax error, relative to the expression (not the file).
syntaxErrors
array
Lexer/parser errors in an expression. Each has stage (lex or parse), code (the engine's error name, such as expectedTokenKind for M or missingOperand for DAX), message, line, column, and endLine/endColumn (the offending token's last character, inclusive). Fields the engine does not know are omitted: lex errors, and parse errors at the end of the input, have no end position.
Usage/argument error, IO failure, or pre-condition violation.
Handlers override the default via TomixResult.Fail(..., exitCode: 2). If no exit code
is specified, the default is 1. Command-line parse errors (unknown option, missing
required argument, invalid option value) also exit 2.
Emitted by MutationRunner and handlers that participate in the mutation lifecycle
(add, rm, set, mv, replace, format, bpa run --fix,
bpa rules ignore/unignore).
Code
Exit
Trigger
TOMIX_MUTATION_UNSUPPORTED_PROVIDER
1
The model provider does not implement IModelMutationSession.
TOMIX_MUTATION_UNSUPPORTED
1
A NotSupportedException was thrown during mutation.
TOMIX_ADD_OPTION_UNSUPPORTED
1
An add option was supplied for an object type that cannot consume it (e.g. --columns on a CalcGroup).
TOMIX_RENAME_BREAKS_REFS
1
--strict-refs was set and the rename (set --set name=..., mv) would leave DAX expressions referencing the old name. By default renames rewrite referencing DAX automatically, so this only fires for references that cannot be rewritten (role RLS filters, or a bare 'Name' when a table and a calendar share the renamed name) — or, under --no-fix-refs, for any reference. Without --strict-refs the rename proceeds with a warning listing the objects left broken.
TOMIX_RM_BREAKS_REFS
1
The object being removed (rm) is still referenced by DAX expressions. Unlike a rename there is nothing to rewrite, so the removal is blocked and the message lists the referencing objects; --force removes anyway and reports the now-broken references. Structural references (relationships, sort-by, hierarchy levels, perspective and translation entries, role permissions) never block — they are cascade-removed with the object.
TOMIX_MUTATION_INVALID_VALUE
1
An ArgumentException was thrown — invalid argument value.
TOMIX_MUTATION_FAILED
1
An InvalidOperationException was thrown — generic mutation failure.
Emitted by get, deps, and format --path when a model object path fails to resolve.
Code
Exit
Trigger
TOMIX_OBJECT_NOT_FOUND
1
The object path matched zero objects. Includes a hint.
TOMIX_OBJECT_AMBIGUOUS
1
The object path matched more than one object.
TOMIX_PROPERTY_NOT_FOUND
1
get --query named a property the object does not have, or no object in a get --where scope has the filtered property. The hint suggests the closest property, or lists the valid ones when nothing is close. An annotation: or translation: token that is simply unset is not an error; it reads back empty.
bpa run --dry-run was passed without --fix, or together with --revert. --dry-run previews fixes, so it needs --fix.
TOMIX_BPA_INVALID_FAIL_ON
2
Invalid --fail-on or --bpa-fail-on value (expected: error, warning).
TOMIX_BPA_RULE_EXISTS
2
bpa rules add was given an ID the rules file (or the model's BestPracticeAnalyzer annotation) already has. Change it with bpa rules set, or remove it first.
TOMIX_BPA_RULE_FIELD_REQUIRED
2
bpa rules add is missing --name, --scope, or --expression (the message names which); bpa rules set was given no field to change; or a name or expression was set to an empty value.
TOMIX_BPA_RULE_ID_REQUIRED
2
A bpa rules subcommand that edits a rule was called without a rule ID.
TOMIX_BPA_RULE_INVALID_SCOPE
2
bpa rules add/set --scope named an unknown object type or no type at all. The hint lists the valid scopes.
TOMIX_BPA_RULE_INVALID_SEVERITY
2
bpa rules add/set --severity was not error, warning, info, 3, 2, or 1.
TOMIX_BPA_RULE_NOT_FOUND
2
bpa rules show, disable, or ignore was given an ID that no loaded rule has. The hint names up to three IDs that contain the input; disable and ignore accept --allow-unknown to use the ID anyway. bpa rules set and remove fail with it when the edited rules file or model annotation has no rule with that ID; for a built-in rule, the hint points to bpa rules disable.
TOMIX_BPA_RULES_FILE_EXISTS
2
bpa rules init found an existing rules file. Pass --force to replace it with an empty one.
TOMIX_BPA_RULES_FILE_NOT_FOUND
2
bpa rules set or remove found no rules file. Create one with bpa rules init or bpa rules add.
TOMIX_BPA_RULES_FILE_REMOTE
2
bpa rules add/set/remove/init was pointed at a remote --rules-file URL, which can't be edited. Download it and pass the local path.
TOMIX_BPA_RULES_LOAD_FAILED
2
Failed to load the BPA rules catalog, or a rules file or model BestPracticeAnalyzer annotation being edited is not a JSON array of rules.
TOMIX_BPA_RULES_TARGET_CONFLICT
2
bpa rules add/set/remove was given both a model and --rules-file. A model edits its BestPracticeAnalyzer annotation; --rules-file edits that file. Pass one.
TOMIX_BPA_VERTIPAQ_STATS_MISSING
0
Warning, not a failure. The deploy BPA gate did not check rules that read Vertipaq_* statistics, because the model has none. The message names the rules. Collect the statistics with tx vertipaq --annotate --save on a deployed model, or on a local model connected to one in workspace mode.
TOMIX_BPA_VIOLATIONS
1
BPA gate blocked the operation: violations at or above the configured threshold were found (with deploy --fix-bpa, they remained after auto-fix). Rules that could not be evaluated count as error-severity violations and are named in the message. Use --skip-bpa to bypass.
deploy --profile selected an existing profile without a server; deploy requires a remote profile.
TOMIX_DEPLOY_UNSUPPORTED
2
The source model cannot be deployed (wrong provider/type).
TOMIX_DEPLOY_FIX_UNSUPPORTED
2
deploy --fix-bpa was requested but the provider session does not implement IModelMutationSession.
TOMIX_DEPLOY_INVALID_FLAGS
2
Contradictory deployment scope: --deploy-full combined with a granular --deploy-* flag, or a dependent flag without the one it refines (--deploy-policy-partitions without --deploy-partitions, --deploy-role-members without --deploy-roles).
query called without query text: pass it positionally, via --query, --file, or piped stdin.
TOMIX_QUERY_INPUT_CONFLICT
2
More than one query source was passed: the positional text, --query, and --file are mutually exclusive; choose one.
TOMIX_QUERY_FILE_NOT_FOUND
2
The --file path does not exist.
TOMIX_QUERY_BAD_PARAM
2
A --param value was not formatted as name=value.
TOMIX_QUERY_OUTPUT_FORMAT
2
-o/--output-file could not resolve a json or csv format (pass --output-format json\|csv or use a .json/.csv extension).
TOMIX_QUERY_INVALID
2
The query does not start with EVALUATE, DEFINE, or SELECT; bypass with --no-validate.
TOMIX_QUERY_NO_REMOTE_TARGET
2
query could not resolve a live endpoint (default connection is local and no remote workspace-mode secondary is set).
TOMIX_QUERY_UNSUPPORTED
2
The provider session does not implement IModelQuerySession (e.g. a local TMDL/BIM model).
TOMIX_QUERY_FAILED
1
The query was rejected or failed on the server (DAX error, no permissions, timeout, etc.).
The performance options are best-effort and do not have dedicated error codes: --trace and
--cold require admin rights on the endpoint (and are unavailable on shared-capacity Power BI).
When they cannot be honored, tx query prints a one-line warning to stderr, still returns the
rowset, and exits 0. When --trace was requested, a nulltimings field is always accompanied
by such a warning.
Emitted by test (DAX regression tests against a live model).
Code
Exit
Trigger
TOMIX_TEST_PATH_NOT_FOUND
2
The path argument does not exist.
TOMIX_TEST_NONE_FOUND
2
No .dax test files were found under the path (or none match --filter).
TOMIX_TEST_BAD_PARAM
2
A --param value was not formatted as name=value.
TOMIX_TEST_NO_REMOTE_TARGET
2
test could not resolve a live endpoint (default connection is local and no remote workspace-mode secondary is set).
TOMIX_TEST_UNSUPPORTED
2
The provider session does not support queries (e.g. a local TMDL/BIM model).
TOMIX_TEST_UPDATE_FAILED
1
An .expected.json snapshot could not be written during --update.
Test failures themselves carry no diagnostic code: a run whose tests fail (or are missing
their snapshot) renders the full report and exits 1, mirroring bpa run. test also reuses
TOMIX_NO_PROVIDER and TOMIX_AUTH_REQUIRED.
Emitted by policy mutations (set/rm) and refresh --policy-only.
Code
Exit
Trigger
TOMIX_REFRESH_POLICY_OPTIONS_CONFLICT
2
Invalid policy-only scope, conflicting refresh flags, or nonpositive parallelism.
TOMIX_REFRESH_POLICY_NOT_FOUND
1
rm/refresh --policy-only targeted a table that has no incremental refresh policy.
TOMIX_REFRESH_POLICY_INVALID
1
set produced validation errors (missing range parameters, source expression not referencing RangeStart/RangeEnd, incoherent granularity/periods, incompatible compatibility level) and --force was not passed.
TOMIX_REFRESH_POLICY_UNSUPPORTED
2
apply targeted a session that is not XMLA-backed (partition generation runs on the server).
TOMIX_REFRESH_POLICY_APPLY_FAILED
1
The server rejected the apply operation.
Policy commands also reuse TOMIX_OBJECT_NOT_FOUND (table missing), TOMIX_REFRESH_NO_REMOTE_TARGET (refresh --policy-only with no remote endpoint), TOMIX_NO_PROVIDER, TOMIX_AUTH_REQUIRED, and the TOMIX_MUTATION_* / TOMIX_STAGE_* families via the shared mutation runner. Validation findings surfaced in the result payload (e.g. range_parameter_missing, granularity_order, no_polling_expression) are lowercase snake tokens, not TOMIX_ diagnostic codes.
Authentication is required but no credentials were provided.
TOMIX_AUTH_SECRET_REQUIRED
2
A service-principal login needs a secret and none was provided: no source given, empty stdin under --password -, an empty secret file, or an empty interactive prompt.
TOMIX_AUTH_SECRET_SOURCE_CONFLICT
2
--password - and --password-file (or the certificate-password equivalents) were combined; choose one.
TOMIX_AUTH_SECRET_FILE_NOT_FOUND
2
The --password-file / --certificate-password-file path does not exist.
Codes carried on the issues inside a validate result (not top-level diagnostics; the
command exits 1 when any error-severity issue is present). DAX0001–DAX0003 and
DAX0006 come from the offline DAX reference scan, DAX0004/DAX0005 from the offline DAX syntax check's
token pass, and DAX0007–DAX0009 from its grammar pass (the first grammar error only, and
only when the tokens are sound). The syntax check runs first — a broken expression reports
only its syntax issues; TOMIX_* codes
come from structural integrity checks.
Code
Severity
Trigger
DAX0001
Error
A DAX expression references a table that does not exist in the model.
DAX0002
Error
A DAX expression references a column that does not exist on the named table (and no measure by that name exists).
DAX0003
Warning
An unqualified [X] reference resolves to no measure or column anywhere in the model, or is a column the expression builds itself (ADDCOLUMNS, SUMMARIZE, GENERATESERIES, ...) used outside the table that has it. Columns the expression builds are not reported where a row of their table is in context (inside FILTER, SUMX, and other iterators over it, including through a VAR). Warning-severity because offline analysis cannot be certain.
DAX0004
Error
A DAX expression contains a character that starts no DAX token, or an unbalanced parenthesis/brace. The expression's reference checks are skipped.
DAX0005
Error
A DAX expression contains an unterminated string, table name, column reference, or block comment. The expression's reference checks are skipped.
DAX0006
Error
A measure or calculated column expression directly references itself.
DAX0007
Error
The DAX parser found a token where a comma, a closing bracket, or the end of the expression belongs: a missing comma between arguments (SUM(a b)), or text left over after a complete expression. The expression's reference checks are skipped.
DAX0008
Error
The DAX parser found an operator, a closing bracket, or the end of the expression where an operand belongs (1 +, 1 * * 2, f(x + )). The expression's reference checks are skipped.
DAX0009
Error
A VAR has no = after its name, or a VAR block has no RETURN. The expression's reference checks are skipped.
TOMIX_BROKEN_RELATIONSHIP
Error
A relationship endpoint refers to a missing column.
TOMIX_BROKEN_SORT_BY
Error
A column's sort-by column does not exist on its table.
TOMIX_BROKEN_LEVEL
Error
A hierarchy level is bound to a column that does not exist on its table.
TOMIX_MODEL_LOAD_FAILED
Error
The model could not be opened or snapshotted at all (e.g. TMDL with unresolvable references); the provider's message is passed through.
No registered provider can open the model. A model source that exists on disk but cannot be read reports TOMIX_MODEL_LOAD_FAILED instead, naming the unreadable path.
TOMIX_PROVIDER_AMBIGUOUS
1
More than one registered provider claims the model reference. Provider CanOpen contracts are mutually exclusive, so this indicates a provider-registration bug, not a problem with the model.
TOMIX_MODEL_LOAD_FAILED
2
The model source could not be loaded: a provider matched but loading failed (unparsable TMDL/BIM, unresolvable references), or the source exists on disk but cannot be read at all (permissions), in which case no provider matched and the message names the unreadable path. The command never ran.
TOMIX_NO_MODEL
2
No model reference was provided and none could be inferred.
TOMIX_CONNECT_FAILED
1
connect failed to establish a session.
TOMIX_INTERACTIVE_REQUIRED
1
An interactive-only flow (connect --remote, a valueless -w) was invoked without a TTY (e.g. --non-interactive, --quiet, redirected input, or json/csv output). Pass the workspace/model explicitly.
TOMIX_REMOTE_LIST_FAILED
1
Listing workspaces or models failed (Power BI REST or XMLA error) during an interactive connect or connect <server> --list.
TOMIX_DATABASE_NOT_FOUND
1
The database/model name was not found on the server.
TOMIX_DATABASE_REQUIRED
2
The endpoint hosts more than one database/model and none was named. List them with tx connect <server> --list, then pass one with -d/--database.
TOMIX_DEPS_PATH_REQUIRED
2
get --deps (or deps) called without an object path.
TOMIX_SINGLE_OBJECT_REQUIRED
2
get --query or get --deps was given a path that selects a set (a wildcard such as Sa*, a container such as Sales/Measures, or --ls/--where). Name one object.
TOMIX_UNUSED_PATH
2
get --unused (or deps --unused) was given a path; it scans the whole model.
TOMIX_INVALID_WHERE
2
A get --where value is not Prop=Value.
TOMIX_FIND_INVALID_REGEX
2
find --regex called with an invalid regular expression pattern.
TOMIX_UNKNOWN_OPTION
2
An unrecognized --option would have been bound to a positional argument (e.g. a typo'd flag). Put -- before positional values that must start with -.
TOMIX_UNKNOWN_COMMAND
2
The subcommand name is not one tx (or the named command group) has, e.g. tx lss. The hint suggests the closest command. A command group run with no subcommand (e.g. tx bpa) is not an error: it prints the group's help and exits 0.
TOMIX_USAGE
2
The command line does not parse: a required argument or option value is missing, a value is not one the option accepts, or there is an extra argument. The hint names the command's --help.
TOMIX_QUIET_COLLISION
2
Text was passed right after -q, but -q means --quiet and never consumes a value: on query the text would run as the positional query with quiet on, and on get it was read as the optional [model] path. Pass query text positionally or via --query.
TOMIX_MOVE_UNSUPPORTED
1
mv across tables called with an unsupported path shape; a cross-table move needs a Table/Measure source and destination. Moving a non-measure across tables surfaces as TOMIX_MUTATION_UNSUPPORTED from the provider.
TOMIX_MOVE_INVALID_PATH
2
mv source or destination is missing an object name (empty path, trailing /).
TOMIX_MOVE_NOOP
1
mv source and destination are identical; nothing to rename.
TOMIX_REPLACE_PATTERN_REQUIRED
2
replace called without a search pattern.
TOMIX_SET_PROPERTY_REQUIRED
2
set called without a property to set.
TOMIX_FORMAT_UNSUPPORTED_LANGUAGE
2
format called with an unsupported expression language.
TOMIX_FORMAT_FAILED
1
format could not format the inline expression (--expression) or the object (--path), or a whole-model run had failed expressions and applied nothing (the result rows are still written; each failed row's error says why). DAX and M are both formatted offline. The message includes the formatter's error details; DAX or M that does not lex or parse also carries line, column, and syntaxErrors (plus objectPath for --path).
TOMIX_COMPLETION_UNSUPPORTED_SHELL
2
completion called with an unsupported shell name.
TOMIX_COMPLETION_SHELL_REQUIRED
2
completion called without its required shell argument.
TOMIX_PROFILE_TARGET_REQUIRED
2
A new profile has no usable remote, local-model, Desktop, or active-session target.
TOMIX_INVALID_OUTPUT_FORMAT
2
--output-format value is not one of: auto, text, json, csv, tmsl, bim, tmdl.
TOMIX_INVALID_TYPE
2
--type value is not a known object kind; the hint lists the valid types.
TOMIX_CONFIRMATION_REQUIRED
1
A destructive action needed confirmation but prompting was unavailable (--non-interactive, --quiet, json/csv output, or redirected stdin/stderr). Pass --yes.
TOMIX_OPTION_CONFLICT
2
Mutually-exclusive options were combined (e.g. --recent with a model path, --profile with an explicit server/database). The message names the pair; which options conflict is command-specific, so branch on the code rather than the wording.
TOMIX_RECENT_INVALID
2
--recent was given a value that is not a positive index (1 = most recently used).
TOMIX_RECENT_NONE
1
--recent was used but no connection has been made yet. Connect once with tx connect <server> <database>.
TOMIX_RECENT_OUT_OF_RANGE
1
--recent <n> is higher than the number of stored connections; the message states how many exist.
TOMIX_RECENT_INDEX_REQUIRED
2
A valueless --recent needs its interactive picker, but prompting was unavailable (--non-interactive, --quiet, json/csv output, or redirected stdin/stderr). Pass --recent <n>.
TOMIX_WORKSPACE_PRIMARY_REQUIRED
2
connect -w was given without enough of a primary connection to mirror from (needs <server> <database>, or a local path). A missing value, not a conflict — see TOMIX_OPTION_CONFLICT for that.
TOMIX_WORKSPACE_UNREACHABLE
1
connect -w reached the primary model but could not reach the workspace mirror's server. The connection is left unchanged.
TOMIX_OUTPUT_FORMAT_UNSUPPORTED
2
The command cannot render the requested --output-format; the message lists the formats it supports.
TOMIX_CONFIG_CORRUPT
2
~/.tomix/config.json exists but does not parse. Repair it manually or reset it with tx config init --force; help, version, doctor, and config recovery paths remain available.
TOMIX_UNEXPECTED
1
An unexpected exception reached the top-level handler. The stack trace is only printed under --debug; with --error-format json it is embedded as a detail field in the envelope so stderr stays valid JSON.