Troubleshooting
Start with the failing stage and preserve its message, configuration and model
identity. Typed conversion failures raise a HeliaAotError subclass that may
include an actionable hint; a golden-data archive the loader cannot parse is
one of them, a GoldenDataError. Unexpected exceptions retain their
traceback. A traceback alone does not tell you whether the model,
configuration or compiler is at fault.
Find the next check
Section titled “Find the next check”| Symptom | Check | Next action |
|---|---|---|
| Configuration fails before conversion | Field names, enum values and the validation message | Compare the setting with the Configuration reference. |
| A placement rule has no effect | Tensor kind spelling, actual tensor id and rule precedence | Use constant, persistent or scratch (in any case); specify both type and id to override a type rule. |
| The model uses operators heliaAOT does not support | The UnsupportedModelError message, which lists each operator type with its node count and first node |
Check the operator catalog; re-export without those operators, or register them as custom operators from the Python API. |
| A platform field is ignored | Whether platform.name is registered |
Use memory constraints for this model’s budget, or define a complete custom target under an unregistered name. |
| No kernel applies | The node’s dtype, shape, options and target capabilities | Check operator restrictions; precision is determined by model tensors. |
| Golden archive cannot load | Path relative to the process, numeric arrays, required input_N/output_N keys, and each array’s element count and dtype |
Regenerate or correct the archive; keep verification enabled when claiming numerical agreement. |
model_run returns 14 |
Successful model_init for the context |
Check initialization’s return value; calling context_init alone is insufficient. |
model_run returns 200 |
Staged constants and hydration latch | Complete hydration and mark it at the helper’s call point during initialization. |
| Outputs mismatch | Input bytes, initial state, iteration count, golden source and tolerance units | Reproduce the first mismatch and inspect those contracts before changing a tolerance. |
If the message remains unexplained, report the full traceback, package version, target, resolved configuration and the smallest model or node description that reproduces it. Include whether failure occurred during conversion, build, initialization or inference.
Exit codes
Section titled “Exit codes”A typed failure prints an Error: line and its hint, and exits with the code
its class declares. The Errors reference lists
each class’s code, the same exit_code the error carries in Python, and the
command line reference lists every
code.
- 2 when your input is rejected: the command line, the configuration, a file it names such as the model, the golden data or the output location, the model type or format, or the target, whether before or during conversion.
- 1 when a valid request fails while converting.
A configuration that fails validation prints error: 1 validation error while parsing arguments (with the count of errors) and one line per error, with no
separate hint line, and an invalid flag value prints the command line’s usage
error; both exit 2.
The error classes
Section titled “The error classes”Every class below also inherits the matching standard-library exception, so
code already catching ValueError or OSError keeps working. The class list,
with the base types, exit codes and docstrings as the code declares them, is in
the Errors reference.
HeliaAotError
Section titled “HeliaAotError”The base class for typed conversion failures. Catch it to handle that family. Seeing it raised directly, rather than one of its subclasses, is unusual.
ConfigValueError
Section titled “ConfigValueError”A configuration value is invalid for the requested conversion. Also a
ValueError.
Read the hint: it names the setting.
ConfigValueErroris what an operator raises when no kernel applies to a node, withexit_code1; the hint then asks you to check that node’s dtype, shape and options against what a kernel supports, and the operator catalog is the list.- A configuration rejected on its own or against the target raises the
subclass
InvalidConfigError, soexcept ConfigValueErrorcatches both.
InvalidConfigError
Section titled “InvalidConfigError”The configuration is rejected on its own or against the target. A
ConfigValueError, and its exit_code is 2.
Read the hint: it names the setting.
- An unknown configuration key is one: the message names the key, where it
appeared and, when one is close, the nearest valid key. From Python,
ConvertArgs.from_yamlraises it directly, and construction ormodel_validateraises it inside a pydanticValidationError. - A removed key or value is one too, and its hint names the replacement.
convert()raises it directly for an unknown platform, an unknownmemory.planner_optionsortransforms[].optionskey, a transform option value its type rejects, an unknown transform name or a transform listed more than once, anoperators[]attribute key or value no operator the rule reaches takes, and a memory constraint or pin the target cannot honour.
A tensor read as quantized that carries no scale or no zero point raises a
ConfigValueError, and the command line exits 1. The message names the operator that reads the tensor.
Re-export the model with full-integer quantization, so every int8, uint8 and
int16 tensor an operator reads carries a scale and a zero point; the hint says
the same.
ModelLoadError
Section titled “ModelLoadError”The input model could not be found or read. Also an OSError, but not a
FileNotFoundError, since a damaged model is not a missing one. The CLI exits
2.
It is raised for a missing file, for a file without read permission, for a directory or a git-lfs pointer in place of the model, and for a file that cannot be decoded as a LiteRT flatbuffer or holds no subgraphs: empty, truncated or another format.
- Check
model.path, rungit lfs pullfor a pointer, and re-export a damaged file. A file that decodes but is damaged inside can still fail later, possibly with an untyped exception and traceback. - An out-of-range
model.subgraph, an unknownmodel.typeor an unsupported file extension is anInvalidConfigErrorinstead.
UnsupportedModelError
Section titled “UnsupportedModelError”The model uses a structure or a dtype heliaAOT cannot lower. Also a
ConfigValueError, and so a ValueError: a handler for ConfigValueError
catches it, and keeps catching an operator rejection that a later release
raises as this narrower class.
The graph was recognized, so the message names the construct and the hint states the supported form. Read the hint before changing anything: the fix is usually in how the model was exported, not in the conversion.
A recurrent loop whose weights are dequantized inside the loop body, for instance, is a weight-only FP16 export rather than a native FP16 model; see Precision.
Operators heliaAOT does not support. Raised before any operator is parsed,
listing every operator type in the model that has no lowering, with its node
count and first node index. An operator code the LiteRT schema does not name
is listed as UNKNOWN(<code>).
Check the operator catalog, then re-export the model without those operators or, from the Python API, register them as custom operators.
Unresolved dynamic tensor shapes after propagation. Raised as an
UnsupportedModelError while propagating tensor shapes, in the command line’s
Analyze group, when a
tensor’s LiteRT shape_signature holds a negative dimension that shape
propagation could neither resolve from the concrete input shapes nor confirm.
- The message lists the tensors by their LiteRT indices in the subgraph,
written as strings, so
0is the first tensor. Run with--verbose 2to see, per tensor, the signature and the shape propagation reached. - A dynamic batch dimension on the model input resolves on its own, and
shape-building subgraphs rooted at
SHAPEare evaluated together with shapes during propagation. - The usual cause is a shape that depends on a runtime value. Fix the export so the shape is concrete; the hint says the same.
OutputExistsError
Section titled “OutputExistsError”An output path already exists and --force was not given. Also a
FileExistsError. The CLI exits 2.
Pass --force to overwrite, or point module.path somewhere else. The same
error guards the residency report.
- A
module.paththat names a file, a.zipor.packpath that names a directory, a symbolic link to nothing, a module directory (module.nameundermodule.path) that is a symbolic link, which is neither written through nor replaced, a location without write or search permission, or a file name too long for the file system is anInvalidConfigErrorinstead, also exit 2, raised before the model loads where it can be. - On Windows the write-permission check sees only a read-only attribute, so a location you cannot write may still fail when the module is exported.
GoldenDataNotFoundError
Section titled “GoldenDataNotFoundError”An explicitly supplied golden-data archive could not be found. Also a
FileNotFoundError, so existing Python callers can catch that standard type.
The CLI prints the error and its hint, then exits with code 2 without a
traceback, as for any other rejected golden data. Set test.golden_data (or --test.golden-data) to an existing,
readable .npz file, or regenerate the archive at that path. Keep numerical
verification enabled when claiming agreement with the reference.
GoldenDataKeyError
Section titled “GoldenDataKeyError”A supplied golden-data archive is missing a required tensor key. Also a
KeyError.
Regenerate the archive with an input_N and an output_N entry for every
model input and output, which is what the hint asks for. The CLI exits 2.
GoldenDataError
Section titled “GoldenDataError”A supplied golden-data archive cannot be read, is not a readable .npz, or
has an array without its tensor’s element count and dtype. Also a
ValueError.
The CLI exits 2. For a file it cannot open, such as one without read
permission, check the path and permissions. For a mismatch, the message names
the key, the tensor and both shapes and dtypes. Save the archive with numpy.savez, one array per input_N and
output_N key, each holding its tensor’s element count in its tensor’s dtype.
ReferenceExecutionError
Section titled “ReferenceExecutionError”Automatic reference setup, execution or worker communication failures raise
this error (also a RuntimeError), and the CLI exits 1. This does not
attribute the failure to invalid user input.
- The diagnostic identifies the model and phase, and available remote tracebacks are printed; unexpected worker Python failures retain theirs.
- Supply
test.golden_data(or--test.golden-data) from an independent reference when the backend cannot execute the model; useskip_verificationonly when output verification is intentionally omitted.
ModelStructureError
Section titled “ModelStructureError”A tensor reference, producer or alias in the graph is ill-formed. Also a
RuntimeError. The violations it names:
- an operator or the model names a tensor that does not exist, two operators produce one tensor, or an operator produces a constant;
- an alias chain is broken, a tensor that owns its storage (persistent state, pinned, a model input, addressed by an NPU command stream) is itself an alias, or an alias reaches persistent, pinned or NPU-addressed storage;
- a constant aliases a non-constant, or a model output aliases a constant.
The message names the stage (the loaded model or a graph transform) and the first violations. After a custom transform, fix or disable that transform. After a built-in transform it is a heliaAOT defect; please report it. In the loaded model, the model file is malformed: re-export it with the LiteRT converter.
OperatorOrderError
Section titled “OperatorOrderError”An operator reads a tensor that a later operator produces. Also a
RuntimeError.
The message names the stage (the loaded model or a graph transform), the operator, the tensor and its producer. After a custom transform, fix or disable that transform. After a built-in transform it is a heliaAOT defect; please report it. In the loaded model, re-export the model with the LiteRT converter.
TemplateRenderError
Section titled “TemplateRenderError”A codegen template referenced context its handler did not supply. Also a
RuntimeError.
This is a heliaAOT defect, not a problem with your model, and the hint says so. The error names the operator and, where it can, the template and the line. It is reachable from a valid model, so please report it with the model or a description of the failing node.
OperatorIdError
Section titled “OperatorIdError”An operator id is not one the generated C can use. Also a ValueError.
Code generation names each operator’s C functions and source file by its id, so an id must be the importer’s form: a decimal integer from 0 to 2147483647 without leading zeros, used by no other operator. The CLI exits 1.
The importer numbers operators that way, so a bad id comes from a custom parser or transform: give each operator it creates or renames a unique numeric id. The message names every operator whose id breaks the rule.
RegistryFrozenError
Section titled “RegistryFrozenError”A frozen registry, or a context that does not allow overrides, was changed.
Also a RuntimeError.
Register custom parsers, operators and transforms in a customizer passed to
build_default_registry_context, which runs before the context is frozen. To
replace or remove a built-in entry there, pass allow_override=True.
DuplicateRegistrationError
Section titled “DuplicateRegistrationError”A registry, or the platform registry, already holds the key. Also a
KeyError.
Pass overwrite=True to Registry.register to replace the item, or use
another key. Platform names must be unique in any case, so register a custom
platform under a name no registered platform uses.
Before the errors: the warnings
Section titled “Before the errors: the warnings”Warnings can explain why a setting did not take effect. Read them before trusting the resolved configuration or resulting plan.
Ignored platform fields. For a registered target, configured cpu,
speeds, capabilities, preferred_memory_order and min_alignment do not
override the registration. The converter warns and uses the registered
definition. memories is the exception: the sizes it names replace the
target’s for that conversion. See Choosing a target.
When there is no error at all
Section titled “When there is no error at all”Some problems do not raise.
A rule that did not apply. The rule matched nothing, or a higher-priority rule overrode it; see precedence.
- Id-only rules outrank type-only rules; later position decides only between equally specific rules. A rule that other rules override on every operator or tensor it matches logs a warning naming the rules that win. Types match in any case; ids match exactly.
- The resolved attributes are not printed at any verbosity: check the
operator’s header for
<PREFIX>_PUT_CODE_IN_ITCM, the plan’sfixedchoices, and the residency report for tensor placement and ids.
A module that compiles but does not match the reference. Compiling is not
validation. Enable test.enabled, keep skip_verification: false and choose
trusted golden outputs or the host-interpreter oracle. The generated test then
checks agreement within test.tolerance; see the oracle and tolerance
limits.
model_run returning 14 or 200. See
the hydration contract.
- Status
14means model initialization has not completed successfully;context_initalone does not enable a run. - Status
200means staged constants are not marked hydrated after a successful initialization. A replacement hydrate helper must finish populating the arenas and call the mark-hydrated function before returning success, because operator init hooks may immediately read those constants. Marking beforemodel_initis ineffective: itscontext_initcall clears the latch.
A build that will not link or compile. Check the ns-cmsis-nn version floor the generated header enforces, and the float switches the module requires. See Precision.