Diagnostics
Complete reference of all IonPath compiler diagnostic codes. Each code has a severity level, a message template, and guidance on how to fix the issue.
General Validation
Cyclic module import detected: {0}
Module A imports B and B imports A (directly or transitively). Break the cycle by extracting shared types into a third module that both can import.
Duplicate definition of '{0}' in module '{1}'
Two types, messages, or services share the same name. Rename one of them.
Type '{0}' not found or is not a standard builtin type
The base type for an enum or attribute argument is not a valid built-in type. Use a primitive like u1, u4, string, etc.
Type '{0}' is not allowed in attribute arguments
Attribute arguments must be scalar types. You cannot use a message or union type as an attribute parameter.
Attribute '{0}' not found
The referenced attribute is not declared. Either declare it with attribute @name(...); or import the module that defines it.
Unresolved reference to type '{0}'
The type doesn't exist in any imported module. If it's a typo, the compiler will suggest the closest match: "Did you mean '{1}'?" (via Levenshtein distance).
Enum & Flags Validation
Duplicate enum item name '{0}' in enum '{1}'
Two members in the same enum/flags share the same name.
Invalid value '{0}' for enum '{1}'
Enum values must be constant integer expressions (literals or bit-shift expressions like 1 << 3).
Duplicate enum value in enum '{1}'
Two members resolve to the same numeric value.
Enum item '{0}' has overlapping bits with '{2}'
Flags-specific: two members share overlapping bits, which would make them indistinguishable when combined.
Union & Service Validation
Union '{0}' declares shared fields but contains type reference case
Unions with type reference cases (e.g., union R { UserData, ErrorInfo }) cannot also have shared fields. Use inline cases instead.
Method '{0}' declares multiple stream parameters
Only one parameter per service method can be marked as stream.
Circular type reference detected: {0}
Types form a cycle (A → B → A). This would cause infinite recursion during serialization. Break the cycle by making one of the references optional (T?).
Schema Lock Violations (ION0020–ION0029)
These diagnostics fire when the current schema differs from the locked schema in ion.lock.json:
Breaking change: field '{0}' (index {1}) was removed from '{2}'
A field that was locked has been removed. Use --update-lock to acknowledge.
Breaking change: field '{0}' changed index from {2} to {3}
Field order determines wire identity. Reordering breaks all existing clients.
Breaking change: field '{0}' changed type from '{2}' to '{3}'
Changing a field's type changes the wire encoding. Existing clients cannot deserialize.
Breaking change: definition '{0}' was removed
A locked type/service was completely removed from the schema.
Breaking change: definition '{0}' changed kind from '{1}' to '{2}'
E.g., changing a msg to an enum.
Service '{0}' removed method '{1}'
Removing a service method will break existing clients that call it.
Breaking change: method '{0}.{1}' signature changed
Method arguments or return type changed.
Breaking change: enum/flags '{1}' member '{2}' changed value
Changing an enum or flags member's numeric value breaks wire compatibility.
Breaking change: union '{0}' case '{1}' changed index
Union case index is the wire discriminator. Reordering changes the meaning of each case.
Field '{0}' added to '{1}' is not nullable
Adding a required field is safe for new clients but older clients reading the previous schema won't have this field. Consider making it optional (T?).
Module System (ION0040–ION0048)
These diagnostics relate to external module dependencies declared in ion.config.json:
Circular module dependency detected: {0}
Module A depends on B and B depends on A (directly or transitively). Break the cycle by extracting shared types into a third module.
Module '{0}' config not found at path '{1}'
The module path in ion.config.json doesn't point to a directory with a valid ion.config.json. Check that the relative path is correct.
Unknown module '{0}'
A #import references a module that is not declared in the modules section of ion.config.json.
Type '{0}' not found in module '{1}'
The imported type does not exist in the target module. Verify the type name and ensure it is defined in one of the module's .ion files.
Type '{0}' not found in module '{1}'. Did you mean '{2}'?
Similar to ION0043 but the compiler found a close match — check for typos.
Imported type '{0}' from module '{1}' is never used
Remove the unused import to keep your code clean.
Module '{0}' content hash has changed since last lock
The module's source files changed since the lock file was generated. Run ionc lock update to acknowledge.
#use is deprecated
Migrate to the #import { Type } from "module" syntax. See Directives.
Type '{0}' has the same name as a type from module '{1}'
Cross-module name collision. Rename one of the types to avoid ambiguity.
Unused Symbols (ION1001–ION1003)
Informational diagnostics reported when symbols are defined but never referenced:
Type '{0}' is defined but never referenced
The type is not used by any service method, field, or union case. It may be safe to remove.
Import '{0}' is unused
No types from this imported file are referenced. Remove the import.
Field '{0}' in '{1}' is never used
The field is not referenced by any service method.