Error refusal contract¶
User-reachable TorchLens refusals are subclasses of torchlens.errors.TorchLensError and retain
their historical built-in exception compatibility where applicable. Callers should branch on
exc.fields["code"], never on message text. Each refusal covered by this contract also carries a
non-empty exc.fields["remedy"], and its human-readable message ends with that remedy.
The argument and capture-context classes are resolved lazily from torchlens.errors; they do not
add names to the top-level torchlens namespace:
InvalidArgumentError(ConfigurationError, ValueError)ArgumentTypeError(ConfigurationError, TypeError)ArgumentConflictError(ConfigurationError, ValueError)— VALUE-combination conflicts (well-typed options whose values are mutually exclusive, e.g.streaming.path+streaming.on_save) were historically rawValueErrors; the typed refusal preserves that catchability.KeywordConflictError(ConfigurationError, TypeError)— KEYWORD/call-surface conflicts (deprecated kwarg + replacement, grouped option + flat field, two exclusive call surfaces) were historically rawTypeErrors (Python's duplicate-keyword convention); the typed refusal preserves that catchability. The split is site-by-site per git history, never a blanket base.CaptureNotActiveError(CaptureError, RuntimeError)DiagnosticSeverityError(ConfigurationError, ValueError)PayloadUnavailableError(CaptureError, ValueError)RecordBindingError(CaptureError, RuntimeError)
Subpackage refusal families resolve lazily from torchlens.errors as well, so every
user-reachable class has one public catch spelling. The defining subpackage stays the import home,
and class names their subpackage marks experimental keep that status:
torchlens.errors(episode errors):BundleExperimentError(ValidationError, RuntimeError)beside its eagerly-imported episode/bundle siblings.- intervention binding and regions:
BindingPreflightError(ConfigurationError, ValueError),BindingRuntimeError(InterventionError, RuntimeError),RegionError(ConfigurationError, ValueError). - observability:
ObservabilityError(ConfigurationError)and itsStatKernelError,HistorySchemaError,HistoryArtifactError,WatchPlanError,ObserverEventError,SpanError,ProfilerSessionError,WatchRenderErrorsubclasses, plusWatchLifecycleError(CaptureError). - trackers:
TrackersError(ConfigurationError)and itsSinkProtocolError,SinkDeliveryError,TagGrammarError,WatchConfigErrorsubclasses, plusWatchRuntimeError(CaptureError). - kit and appliance refusals:
CheckConfigError(ConfigurationError),CheckLifecycleError(CaptureError),CheckViolationError(CaptureError)(checks);ReadError(TorchLensError, ValueError),ReadInternalError(TorchLensError, RuntimeError)(one-backward attribution);GradFnWalkError(CaptureError)(debug);ModelExplorerExportError(CaptureError, RuntimeError);FeatureShapingError(ConfigurationError, ValueError);SiteInventoryError(ConfigurationError, ValueError);MechInterpError(TorchLensError, RuntimeError);NeuroHandoffError(ConfigurationError, ValueError);PreprocessingAuditError(ConfigurationError, RuntimeError);NormReconstructionError(TorchLensError, RuntimeError);NarrationConfigError(ConfigurationError),NarrationStatsError(CaptureError)(snoop);FittedArtifactError(ConfigurationError, RuntimeError);RenderError(TorchLensError, RuntimeError);RankRenderEndpointError(GraphvizRenderError). - semantic output decode:
DecodeStyleUnknownError(InvalidArgumentError)(codedecode_style_unknown). - warning categories:
PluginLoadWarning(TorchLensWarning)(soft plugin-load failures) andSynthesizedValueReadWarning(TorchLensWarning)(first raw value read on a trace whose inputs were synthesized).
Stable codes¶
| Code | Refusal | Remedy class |
|---|---|---|
accessor_count_by_key_required |
Accessor.count_by() was called with no field name; len(accessor) is the total and a count needs a field to group by |
Pass the field to count by (count_by('module'), count_by('module', 'kind')) |
accessor_count_by_key_unknown |
Accessor.count_by(key) named a field that is not countable on this accessor's records (exc.fields['countable'] lists the declared ones) |
Count by a declared field or any string or int field every record carries |
activation_not_saved |
Requested op activation was not retained by save= (also xarray export with nothing saved, and Trace.reconstruct_output() when the lone output op was not saved, on the live trace or after tl.load) |
Re-run the capture with save= covering the op |
moe_routing_activation_missing |
A lazy MoE routing table needs an unsaved router output; activation identifies its op (PayloadUnavailableError) |
Capture with save='all' to retain expert indices and gate weights, without an activation transform |
activation_address_unmatched |
activations_by_address(address) found no retained activation at that module or buffer address; the message and fields['known_addresses'] list the addresses that do have one (InvalidArgumentError, ValueError lineage) |
Pass one of the listed addresses |
agent_argument_invalid |
An agent-surface tool request violated its declared input schema (missing/unknown key, wrong type, closed-vocabulary miss) | Follow the declared input schema; the refusal names the supported arguments |
agent_artifact_kind_unsupported |
An agent tool was pointed at a non-Trace artifact (Bundle, InterventionSpec, ...) | Load non-Trace artifacts in Python via tl.load(path) |
agent_artifact_load_refused |
Manifest-declared payload entries exceed the single-tool-call load bound | Load it in Python via tl.load(path, lazy=True) where the caller controls the budget |
agent_artifact_unreadable |
An agent tool path names nothing on disk | Pass the path of an artifact saved with trace.save(path) |
agent_continuation_drift |
A paging continuation's artifact, request, ordering, or schema changed between pages | Re-issue the query from page one; stale pages refuse, never silently reinterpret |
agent_limit_invalid |
A requested budget limit is non-positive or exceeds the served ceiling | Requests lower ceilings, never raise them; run the unbounded spelling in Python |
agent_name_unknown |
api_map detail mode named a spelling that is not on the root surface | List the surface with api_map first |
agent_query_ceiling |
A query AST tripped the depth/node/string decoder ceilings | Split or shorten the query; ceilings are DoS bounds, not semantics |
agent_query_invalid |
A query AST violated the closed v1 grammar, or requested a deliberately-refused kind (regex, callables, value predicates) | Use the supported leaves/combinators; value-dependent selection runs in Python |
agent_reduction_invalid |
A payload_stats reduction named a bad dimension or omitted the required ranking metric | Pass an in-range retain_dim and a rank_by metric when the extent exceeds max_rows |
agent_schema_unknown |
The schema tool was asked for an unserved schema id | Fetch the index first; the refusal lists every served id |
agent_tool_unknown |
An agent tool call named an unregistered tool | Use a served tool name; the refusal lists the roster |
agent_view_invalid |
A dump view or fold class id is outside the served vocabulary | Pass view=overview/graph/full; list classes via the folded overview first |
aliasing_parent_not_in_call_args |
Internal invariant: an aliasing contract could not find its parent layer among the function arguments | Report it as a TorchLens bug with the traceback |
attribute_walk_segment_invalid |
An attribute-walk path (experimental attribute addressing) has a malformed segment |
Use dotted names with optional integer indexes, such as blocks[0].attn |
auto_capture_every_invalid |
auto_capture(every=...) was given zero or a negative number |
Pass every as a positive integer |
backend_already_registered |
register_backend was given a name or alias that is already registered |
Pass replace=True or register under another name |
bridge_brain_score_benchmark_invalid |
The Brain-Score bridge was given a benchmark that is not callable | Pass a callable offline benchmark that takes the candidate and returns a score |
bridge_brain_score_not_scalar |
score_parts got a Brain-Score result without exactly one number |
Pass a scalar or one-element score |
bridge_captum_method_invalid |
The Captum bridge was given an object without attribute(...) |
Pass a Captum attribution object, such as IntegratedGradients(model) |
bundle_index_type_invalid |
A Bundle was indexed by something other than a member-name string |
Index by a member name; bundle.names lists them |
compat_layers_required |
from_torchextractor or from_ilg was called without the layers to extract |
Pass layers=[...] or return_layers={...} |
constant_unrealizable |
A captured constant (a closure or global tensor the model read) has no readable host buffer, so its payload cannot be recorded (jax, tf, mlx, tinygrad) | Pass the value as a model input, or make it a concrete readable array before the call |
call_structure_mismatch |
A call's structure does not match what the artifact declares: the executed op sequence differs from the captured one (RunnableErrorCode), or a loaded op carries a raw-pointer keyword such as cdata that replay would hand to a tensor constructor, or a sparse check_invariants keyword that would turn index validation off, refused before the call runs (RunPreconditionError) |
Re-capture the model with the intended call; never replay a bundle whose saved arguments carry raw pointers or switch off sparse index checks |
edit_hook_factory_missing |
An edit spec without a runtime hook factory was asked for its hook | Build the edit with a TorchLens edit helper |
escape_exemption_budget_exceeded |
Internal invariant at import: the audited callable-escape exemption list outgrew its budget | Remove an exemption, or raise the budget in the change that adds its regression test |
explicit_seed_unsupported |
seed= was requested on a backend whose preview cannot seed the framework RNG (mlx, tinygrad) |
Omit seed and seed the framework's own RNG state before calling |
feature_maps_site_invalid |
feature_maps was pointed at a layer it cannot plot (multi-pass without a pass, or not saved) |
Pick saved single-pass layers or name a pass, such as conv1:2 |
feature_maps_spatial_missing |
feature_map_evolution found no spatial [N, C, H, W] activations |
Capture with save= covering the conv layers |
grad_options_max_intermediate_invalid |
GradOptions.max_intermediate_grads is not an integer of at least 1 (JAX, MLX, Paddle, TensorFlow backends) |
Pass an integer of at least 1 |
hf_processor_unresolved |
The transformers bridge could not resolve an AutoProcessor for the model |
Load the model with from_pretrained(...) or run the processor yourself |
injected_rows_unfinalized |
Internal invariant: loaded injected-op rows were never finalized (a load path skipped rehydrate_trace) |
Load with tl.load(path); otherwise report it as a TorchLens bug |
interventions_unsupported |
intervene= was requested on a backend that declares no intervention support |
Drop the interventions, or capture with a backend that declares them (tl.report.doctor() names each backend's capabilities) |
jax_control_flow_rejected |
A JAX control-flow primitive was met under jax_control_flow='reject' |
Pass jax_control_flow='unroll' or 'region' |
jax_effects_unsupported |
The traced JAX function has side effects (callbacks, io, ordered effects) | Remove the side effects; the JAX backend captures pure functions |
jax_nested_primitive_unsupported |
The traced JAX function uses a nested primitive or jaxpr the backend cannot inline | Move the primitive out of the traced function |
lovely_tensors_has_no_lovely_function |
The installed lovely_tensors has no lovely() formatter; TorchLens will not monkey-patch instead |
Upgrade lovely-tensors, or call it directly |
mlx_unwrapped_policy_invalid |
The MLX unwrapped-op policy is not one of the allowed values | Pass one of the policies the message lists |
module_identity_mode_unsupported |
The requested module_identity_mode is not available for this backend's model object (for example tinygrad object_module on a raw callable, or a mode the paddle preview does not declare) |
Use the mode the refusal names for that backend |
module_metadata_missing |
A module reached the torch module stack without TorchLens metadata | Capture through tl.trace; otherwise report it as a TorchLens bug |
module_stack_mismatch |
Internal invariant: the torch module stack top is not the frame being popped | Report it as a TorchLens bug with the traceback |
module_stack_underflow |
Internal invariant: the torch module stack was popped while empty | Report it as a TorchLens bug with the traceback |
observer_signal_invalid |
tap/span observer signal is not forward, backward or both |
Pass one of those three |
position_edit_invalid |
tl.positions got an unsupported positions= (not an int, a non-empty int list, a slice, a per-row integer tensor, "first" or "last") or a batch/non-int axis= (InvalidArgumentError; experimental) |
Pass e.g. positions=-1, [0, 3], slice(2, None), or "last" with mask=attention_mask |
position_edit_out_of_range |
An at_positions position falls outside the site value's token axis, or a per-row index tensor has the wrong batch length (HookValueError; experimental) |
Use positions inside the sequence, and one index per batch row |
position_edit_shape_mismatch |
The edit wrapped by at_positions returned a value of another shape, so it cannot be kept at some positions only (HookValueError; experimental) |
Wrap a same-shape edit (ablations, steering, patches) |
raw_graph_workspace_foreign |
Internal invariant: the torch backend received a raw-graph workspace owned by another trace | Report it as a TorchLens bug with the traceback |
recorder_state_uninitialized |
Internal invariant: a recorder was read before its context initialized it (dry_run) |
Enter the recorder context first; from dry_run, report it as a TorchLens bug |
recording_projection_uninitialized |
Internal invariant: a Recording's trace projection was read before it was built | Report it as a TorchLens bug with the traceback |
region_annotation_provenance_missing |
A region replay annotation lacks the importer provenance validation needs | Re-import the model with the importer that wrote the annotation |
rehydrate_recursion_limit |
A saved format 3 artifact's record graph nested deeply enough to exhaust the interpreter recursion limit while rehydrating; the load refuses typed instead of escaping as a RecursionError |
Re-save the artifact from its source trace; a record graph that deep is corrupt or hostile |
replay_gradient_edit_unsupported |
A gradient edit (an ordinary edit or callable on a tl.grad(...) site) reached a forward-only engine: do(tl.grad(site), edit) with engine="replay", or auto without model= and inputs=, or a replaying do on a recipe holding gradient rules. Replay re-executes forward ops only and never runs a backward pass, so the edit has no gradient to edit; nothing is changed (InvalidArgumentError; experimental) |
Replay re-executes forward ops only and cannot edit the gradient at {sites}. Pass model= and inputs= to rerun with the edit armed, then call result.backward(loss) (or pass loss=), or stage it with engine='set_only' and call trace.backward(loss) on this trace |
replay_loaded_trace_has_no_callables |
An edit (do() on the replay engine, or a fork edit) was replayed on a trace loaded from a saved file: a save keeps no capture-time callables or argument templates, so no op can be replayed; refused before any op runs (ReplayPreconditionError) |
Edit a trace captured in this process (tl.trace(model, inputs)), or rerun the model with the edit staged: trace.run(model, inputs) |
replay_downstream_op_raised |
A replay produced an edited value that a downstream op could not consume (an index, shape or dtype path fixed at capture), so the op raised; the refusal names the op, the edit origin and the raised type (fields["raised_type"]), chains the torch error, and commits nothing (ReplayPreconditionError) |
Choose an edit that keeps the edited site inside the range the downstream ops accept, or rerun the model with the edit staged: trace.run(model, inputs) |
replay_param_changed_since_capture |
A replay (do() on the replay engine, including InterventionOptions(differentiable=True), and the later replays of every fork kind) reached a template parameter that changed since capture: a replay template holds the live nn.Parameter, so an optimizer step, load_state_dict, an in-place op under torch.no_grad() or param.data = t would otherwise make the replay silently compute with the new value. Detected by the version counter, storage pointer and shape recorded at capture; an in-place write through param.data (or a numpy or raw-storage alias) is not detected. The fields name param, op and what changed; nothing is changed (ReplayPreconditionError; experimental) |
Re-capture the trace; or pass allow_changed_params=True (InterventionOptions or ReplayOptions) to replay with the current values, recorded in trace.last_run["replayed_with_changed_params"]; for an as-if weight edit use fork.do(tl.param(name), edit) |
root_not_a_bound_module_method |
TLBoundMethodRoot wraps something that is not a bound method of an nn.Module |
Pass a bound method such as model.forward |
grad_selector_nested |
tl.grad(...) was given a GradSelector: a gradient address wraps a forward site once (SelectorCompositionError; experimental) |
Write tl.grad(x), not tl.grad(tl.grad(x)) |
grad_selector_inner_not_forward |
tl.grad(...) was given a node selector (tl.grad_fn, tl.grad_fn(label=...), tl.without_op, tl.grad_input(), tl.grad_output()) or a selector carrying a pass qualifier (tl.in_backward_pass) (SelectorCompositionError; experimental) |
The autograd-node selectors already address gradients at node granularity; use them unwrapped. Put a pass qualifier outside: tl.grad(s) & tl.in_backward_pass(2) |
grad_selector_inner_invalid |
tl.grad(...) was given a list, a mapping or another non-site value (SelectorCompositionError; experimental) |
Pass one site to tl.grad; batch shapes go to the door |
grad_facet_unsupported |
tl.grad(...) was given a facet or head selector (tl.facet, tl.head); gradient facets are not addressable this release (SelectorCompositionError; experimental) |
Edit tl.grad(site) and mask inside a callable |
grad_selection_unsupported |
tl.grad(...) was given a Selection from trace[selector]; gradient selections are not addressable this release (SelectorCompositionError; experimental) |
Use tl.grad(selector) |
runtime_version_unsupported |
The installed framework version is outside the range the backend declares | Install a framework version inside the declared range (the tl.report.doctor() backend row shows the requirement) |
sae_interface_invalid |
The SAE Lens bridge was given an SAE without encode/decode and not callable |
Pass an SAE with encode(...) (and decode(...)) or a callable |
selector_cross_universe_and |
& joined operands from different universes: a gradient address with an activation address (tl.grad(s) & s), a node address with an activation address, or a gradient address with a node address (tl.grad(s) & tl.grad_fn(...)) (SelectorCompositionError; experimental) |
A gradient and an activation address never share a site; use \| for both. Spell a node address alone (tl.grad_fn(label=...)) or use the tensor address tl.grad(s) |
selector_cross_universe_not |
~ negated a union whose branches sit in different universes, such as ~(tl.grad(s) \| s); its complement is not one address set (SelectorCompositionError; experimental) |
Negate inside each branch before joining them, e.g. tl.grad(~a) \| ~a |
selector_module_facet_scope_conflict |
tl.module(a) & facet where the facet selector is already scoped to module b != a |
Drop one of the two module scopes |
selector_signal_mismatch |
& joined a pass qualifier (tl.in_backward_pass) to a bare activation selector (SelectorCompositionError; experimental) |
A pass qualifier needs a gradient address: tl.grad(s) & tl.in_backward_pass(2) |
edit_signal_mismatch |
An activation-only edit (tl.patch_from, tl.mean_ablate, tl.splice_module, torchlens.intervention._helpers.swap_with with a site or trace donor) was attached to a gradient site; the check runs at attach time, before any mutation (replaces the former "Forward intervention helper attached to a backward-only selector will not fire" warning) (InvalidArgumentError; experimental) |
This edit reads activations and the address tl.grad(...) is a gradient; use a neutral edit (tl.scale, tl.zero_ablate, tl.clamp, tl.add_noise, tl.clip_norm or a callable) |
site_spelling_not_unique |
trace[selector] with a spelling that names one thing (a target spec or an exact label) matched several sites (exc.fields['matched']) |
Address one site exactly (a pass-qualified label), or use a set-naming selector (tl.func, tl.in_module, tl.label_contains) to get every match as a Selection |
source_kind_invalid |
Internal source-tensor logging got a source kind outside input, buffer or constant | Pass one of the kinds the message lists |
subspace_basis_dim_mismatch |
A subspace_ablate / subspace_interchange basis indexes a feature axis of another width than the site value's, refused at fire time instead of broadcasting (HookValueError; experimental) |
Build the basis over the site's feature width, or name the right dim= |
subspace_basis_invalid |
A subspace_ablate / subspace_interchange basis is not a non-empty finite [k, d] tensor, is rank-deficient (its span is smaller than the subspace it names), or dim= is not an int (InvalidArgumentError; experimental) |
Pass k linearly independent finite rows over the feature axis and an int dim |
subspace_mode_invalid |
subspace_ablate got a mode= outside zero, mean, resample, or mean= / seed= that do not match the mode (InvalidArgumentError; experimental) |
Pass mean=<tensor> with mode="mean" and seed=<int> with mode="resample" |
subspace_edit_unsupported |
do(subspace(...), edit) got an edit verb with no meaning on the subspace coordinates (a nested projection edit, compose, at_positions, a source= that is an activation-space value, splice_module(input_route="in"), a backward verb, an unlisted verb), or a coordinate edit returned a different shape (InvalidArgumentError; experimental) |
Use the plain verb on the component, or the verb-specific spelling the remedy names (a hook callable receives the coordinates) |
subspace_spec_invalid |
A saved subspace_edit (the portable form of do(tl.subspace(...), verb)) has a malformed stored field at load: the inner verb is not a builtin edit, the basis is not a finite float64 [k, d] tensor, the axis is not an int, origin/basis_sha256/origin_sha256/source_dtype is not a non-empty string, method is not None or a string, orthonormalised is not a bool, the within= mask is not a bool tensor with the basis width on its axis or keeps only part of the basis support at a position, mask_sha256 is missing beside a mask or stored without one, or a stored keyword is one the loader does not know (InvalidArgumentError, argument names the field; experimental) |
Re-save the edit from the session that built it: fork.do(tl.subspace(site, basis, origin=...), edit) then tl.io.save_intervention(fork, path, level='portable') |
subspace_spec_basis_tampered |
A saved subspace_edit's stored rows no longer match their recorded basis_sha256: the rows were changed after saving, so the projection they would apply is not the one recorded (InvalidArgumentError; experimental) |
Re-save the edit from the session that built it (same spelling as subspace_spec_invalid) |
subspace_spec_basis_not_orthonormal |
A saved subspace_edit's stored rows are not orthonormal to 1e-10 (a saved projection always stores the orthonormal rows it applied) (InvalidArgumentError; experimental) |
Re-save the edit from the session that built it (same spelling as subspace_spec_invalid) |
subspace_spec_mask_tampered |
A saved subspace_edit's stored within= mask no longer matches its recorded mask_sha256: the mask was changed after saving, so the positions it would edit are not the ones recorded (InvalidArgumentError; experimental) |
Re-save the edit from the session that built it (same spelling as subspace_spec_invalid) |
affine_source_invalid |
tl.intervention.set_affine_coordinates(weight, bias=...) got a weight that is not a finite real [k, d] tensor, a bias that is not None or a finite real [k] tensor, or (under do(tl.subspace(...))) a weight shaped unlike the basis rows; also at load of a saved spec (InvalidArgumentError, argument names it; experimental) |
fork.do(tl.subspace(site, rotation.T, origin=...), tl.intervention.set_affine_coordinates(weight, bias=bias)) with weight shaped like the basis rows |
affine_source_needs_subspace |
tl.intervention.set_affine_coordinates(...) was applied to a whole site (a site label, tl.units, a capture or replay hook): its [k, d] weight maps the site value to k subspace coordinates, which only a subspace selection defines. Refused at do() for a selection target and when the hook fires at every other door (InvalidArgumentError; experimental) |
fork.do(tl.subspace(site, rotation.T, origin=...), tl.intervention.set_affine_coordinates(weight, bias=bias)) |
pyreft_artifact_invalid |
tl.bridge.pyreft.read(directory) found no directory, no or unreadable config.json, no intkey_<key>.bin (dotted or underscored), a weight file that is not LoReFT's finite weight, bias and rotate_layer of the shapes config.json names, a rotate_layer whose columns are not orthonormal (Gram error above 1e-4; pyreft's float32 training leaves about 1e-7), an intervention key that is not a plain file-name part, a symlinked weight file, or a torch older than 2.6 whose weights_only loader is bypassable (CVE-2025-32434) (InvalidArgumentError, file names it; experimental) |
Point read() at the directory pyreft saved with reft_model.save(directory): tl.bridge.pyreft.read(directory) |
pyreft_artifact_unsupported |
The pyreft artifact holds more than one intervention, or one whose class is not pyreft's LoreftIntervention (InvalidArgumentError; experimental) |
Read a directory with one LoReFT intervention: tl.bridge.pyreft.read(directory) |
pyreft_positions_invalid |
LoreftArtifact.subspace(site, positions=...) got positions that is not a bool tensor, or (given the site from a trace) a mask whose shape is not the site's shape without its trailing feature axis (InvalidArgumentError; experimental) |
positions = torch.zeros(batch, seq, dtype=torch.bool); positions[:, -1] = True |
pyreft_site_invalid |
LoreftArtifact.subspace(site, ...) got a site from a trace whose trailing axis is not the artifact's feature width (a site of another width, or one whose feature axis is not last), or something that is neither a site label nor a site; the refusal names the site, its shape and the artifact's width (InvalidArgumentError; experimental) |
positions = torch.zeros(trace[label].shape[:-1], dtype=torch.bool); positions[:, -1] = True; artifact.subspace(trace[label], positions=positions) with label the site whose trailing axis is the artifact's width |
subspace_projection_composed |
do() got a subspace selection combined with set operators, or an already-resolved subspace selection: neither has one basis to edit through (InvalidArgumentError; experimental) |
Pass the unresolved tl.subspace(...) and restrict it with within=; to edit the support set itself pass tl.units(site, resolved[0].mask) |
subspace_projection_partial_axis |
A subspace within= population selects only part of the basis support along the bound axis at some position, so the component cannot be edited there (InvalidArgumentError; experimental) |
Give within= a mask that is True on every feature of each chosen position |
edit_detached_from_graph |
An edit wrapped in torchlens.intervention.keep_grad(...), or run by InterventionDecision(keep_grad=True), wrote values carrying no autograd graph while the site value had one (reason="edit_detached"), or the site value had no graph (site_has_no_graph), or gradients were disabled (grad_disabled) (InvalidArgumentError; experimental) |
Use a graph-keeping spelling (keep_grad(tl.scale(0.0)) for a zero, keep_grad(tl.intervention.compose(tl.scale(0.0), tl.add(value))) for a fixed value), run with gradients enabled, or drop keep_grad to accept the cut |
keep_grad_edit_invalid |
torchlens.intervention.keep_grad() got a backward-direction edit or an object that is not an edit (InvalidArgumentError; experimental) |
Wrap a forward edit or a hook callable, e.g. keep_grad(tl.scale(2.0)) |
tf_derived_grads_loss_not_scalar |
TensorFlow derived gradients need loss_fn(raw_output) to be a scalar float tensor |
Pass a reducing loss_fn, such as tf.reduce_sum |
tf_derived_grads_no_leaves |
TensorFlow derived gradients found no floating input or trainable variable to differentiate | Pass a floating input or trainable model, or request intermediate_grads |
tf_derived_grads_replay_diverged |
The TensorFlow gradient replay output differs from the captured output | Make the forward deterministic (no dropout, training=False) and capture again |
tlspec_format_unrecognized |
validate_tlspec found a .tlspec format it does not recognize |
Pass a .tlspec written by trace.save in this release |
tlspec_path_not_directory |
validate_tlspec was given a path that is not a .tlspec directory |
Pass the directory trace.save(path) wrote |
torch_tensorbase_unavailable |
The installed torch exposes no torch._C.TensorBase (torch older than 2.1) |
Install torch 2.1 or newer |
trace_forward_kwargs_unrouted |
tl.trace(model, input_ids=...)-style model-input keywords are never silently absorbed; a removed capture option (output_style, output_head, layers_to_save, save_preview) names its replacement instead of the routing remedy |
Pass them via input_kwargs={...}, or use torchlens.bridge.transformers.trace_text for HF text models; for a removed option, follow the named replacement (trace.decode_output(...), save=) |
activation_range_violated |
FINDING (checks kit, collect-class): a probed activation left its caller-declared semantic bounds at a named site (a range probe over the public capture.hooks seam) |
Bounds are the caller's semantic declaration; inspect the named site, then tl.threshold(within=...) on the captured trace |
annotation_backend_unsupported |
Tensor annotation on a non-torch trace | Pass JSON-serializable data instead |
annotation_namespace_invalid |
annotations["user"] is no longer a dict |
Restore the user namespace to a dict |
annotation_not_json_serializable |
Annotation data is neither JSON nor a tensor | Convert arrays to torch.Tensor |
annotation_payload_missing |
annotate() received neither data nor image |
Pass data=, image=, or both |
annotation_tensor_not_portable |
Annotation tensor fails the payload codec | Pass a dense, codec-supported tensor |
appliance_unknown |
trace.using(name) named no registered appliance; the message and fields['registered'] list the registered names (InvalidArgumentError, ValueError lineage; experimental) |
Call trace.using(...) with a listed name, or register one with torchlens.appliances.register(name, factory) |
appliance_name_taken |
tl.appliances.register(name, ...) for a name already registered, without replace=True (ArgumentConflictError, ValueError lineage; experimental) |
Choose another name, or pass replace=True |
appliance_registration_invalid |
An appliance name that is not a str or does not start with a letter followed by letters, digits, _, . or -, or a factory that is neither callable nor a 'module:attribute' path (ArgumentTypeError or InvalidArgumentError; experimental) |
Pass a valid name and a callable factory |
aten_ops_invalid |
CaptureOptions(aten_ops=...) given a value other than False, True or the literal "values" (InvalidArgumentError, ValueError lineage) |
Pass aten_ops=False, aten_ops=True (value-free rows) or aten_ops="values" (rows with their output tensors) |
aten_ops_unavailable |
Trace.aten_ops, Trace.aten_gaps or Op.aten_ops read on a capture that recorded no ATen operations (CaptureOptions.aten_ops was off, the artifact was saved without it, or the trace is a run(fast=True) result); also the kernel-telemetry seam given such a factory (AtenOpsUnavailableError, RuntimeError lineage) |
Re-capture with CaptureOptions(aten_ops=True); Trace.has_aten_ops tells before reading |
artifact_kind_mismatch |
Specialized loader received another artifact kind | Use the matching loader or generic io.load |
recipe_audit_only |
tl.load met a kind: "recipe" artifact saved with Recipe.save(path, level="audit"): a predicate WHERE term or a user callable edit was recorded as a callable placeholder and cannot be rebuilt into a Recipe (ReplayPreconditionError) |
Read intervention.json for the record; to make a loadable recipe, express every WHERE term as a selector (tl.func / tl.in_module / tl.site / tl.label) and every edit as a helper, then save at level "portable" |
recipe_record_malformed |
tl.load met a kind: "recipe" artifact whose intervention.json has no rules list or whose rule is not an object with selector and edit: the record was hand-edited or is not a TorchLens recipe (ReplayPreconditionError) |
Re-save the recipe with Recipe.save(path); a hand-edited or foreign record is not loadable |
artifact_checkpoint_witness_invalid |
Loaded Trace.checkpoint_invocation_witness violates its closed token schema, D1-D6 flag vocabulary, verdict coherence, count geometry, or retained-site relations |
Re-run backward capture and re-save; do not hand-edit checkpoint evidence |
artifact_distributed_scope_invalid |
Loaded Trace.provenance.distributed_scope is outside the closed None / rank_local_shard vocabulary |
Re-save the source trace; do not invent distributed-scope markers |
artifact_executed_flops_record_invalid |
The loaded BackwardPass persisted FLOPs record violates its closed key set (convention, executed_flops, uncounted_ops, rows, unattributed), holds anything but ints, None and short strings, or its rows plus unattributed bucket differ from a known executed_flops (tlspec v10) |
Re-save the artifact from its source capture; do not hand-edit the counted backward record |
artifact_capture_advisories_invalid |
Loaded Trace.annotations["capture_advisories"] rows violate their closed {kind, count, first_location, message} shape (tlspec v9) |
Re-capture and re-save; do not hand-edit capture advisories |
artifact_grad_fn_timing_provenance_invalid |
Loaded Trace.grad_fn_timing_provenance names no supported timing source |
Re-run backward capture and re-save without editing the clock source |
artifact_injection_provenance_invalid |
Loaded Op.call.injection_provenance violates the closed injected-op identity record (host_site_key, spec_rule_id, host_pass, firing_index, nesting_path, local_op_ordinal, output_slot; tlspec v9 entry-dark slot, written by the stage-2 codec) |
Re-capture with log_injections and re-save; do not hand-edit injected-op identity records |
artifact_injection_codec_invalid |
Loaded injected-op rows violate the codec contract: duplicate durable keys, a host site key no retained model op carries, an envelope host_label that is not the pass-qualified label of the op at that site key, a host_pass that is not that op's pass index, a spec spec_rule_id the artifact's own intervention record never ran (adhoc: ids claim no rule and anchor by host alone), model-dataflow entanglement (an injected row claiming parents/children, or a model op referencing an injected label), the intervention-replacement identity on an injected row (the 2026-06-02 carve-out stays scoped to genuine user interventions), or a malformed/absent injection_codec_v1 envelope (closed key set, version, host-anchored label, registry-key callable reference, closed replay-arg grammar). Forged provenance always refuses; degrade-to-unattested is for unresolvable callables only |
Re-capture with log_injections and re-save with one current TorchLens version; do not hand-edit injected-op rows |
artifact_episode_step_invalid |
Loaded Op.episode_step is not a non-negative int/None, or a stamped op rides a capture with no episode declaration (tlspec v9 entry-dark slot; the F-EPISODE read-axis work writes it) |
Re-save from the source capture; do not hand-edit episode-step stamps |
artifact_tl_authored_root_invalid |
Loaded Op.call.tl_authored_root is not a bool/None, or True rides a capture whose root_entry_point is not a bound_method descriptor (tlspec v9 entry-dark slot; written on bound-method captures) |
Re-save from the source capture; do not hand-edit the TL-authored-root marker |
artifact_root_entry_point_invalid |
Loaded Trace.provenance.root_entry_point violates the closed root invocation descriptor grammar (module_call\|bound_method\|function_call + : + identity; written unconditionally on every capture) |
Re-save with a current TorchLens; do not hand-edit the root entry-point fact |
artifact_forward_peak_memory_invalid |
Loaded Trace.cost.forward_peak_memory_reason is not a non-empty string, or explains a forward_peak_memory that is a number (the reason only ever explains a None CPU forward peak) |
Re-save with a current TorchLens; do not hand-edit the forward peak-memory fields |
artifact_backward_peak_memory_invalid |
Loaded Trace.backward_peak_memory_reason is not a non-empty string, or explains a backward_peak_memory that is a number (the reason only ever explains a None CPU backward peak, measure.2) |
Re-save with a current TorchLens; do not hand-edit the backward peak-memory fields |
artifact_intervention_audit_invalid |
Loaded Trace.intervention_audit or Edit.selection_recipe violates its closed row schema or their resolve-digest relation |
Re-apply the intervention and re-save; do not hand-edit audit or recipe rows |
artifact_kernel_telemetry_invalid |
Loaded kernel telemetry violates its closed launch schema or cites a nonexistent primitive sequence / launch index | Re-profile and re-save the trace; do not hand-edit launch or relation rows |
artifact_save_level_invalid |
.tlspec save level is unknown |
Choose a documented save level |
artifact_save_level_unsupported |
Artifact kind cannot provide the requested save level | Choose a level supported by that kind |
artifact_sidecar_invalid |
Loaded Trace.annotations["sidecar"] namespace or an envelope violates its closed {schema_id, version, owner, payload} shape (tlspec v9; payload semantics stay with the owning family's read-time validator) |
Re-attach through torchlens.io.attach_sidecar and re-save; do not hand-edit sidecar envelopes |
artifact_site_key_invalid |
Loaded Op.graph.site_key is partial, malformed, or differs from the byte-exact site_key_v1 recomputation over persisted op structure |
Re-capture and re-save with one current TorchLens version; artifacts at the tlspec v6/v7 boundary may be wholly keyless |
artifact_source_snapshots_invalid |
Loaded Trace.source.snapshots violates the closed per-(path, digest) row schema (tlspec v9 entry-dark slot) |
Re-capture and re-save; do not hand-edit the source-snapshot table |
artifact_structure_evidence_invalid |
Loaded Trace.graph.structure_evidence envelope violates its closed key set / claim vocabularies, or decorates a capture whose structure_only marker is False (tlspec v9 entry-dark slot) |
Re-capture structure-only and re-save; do not hand-edit the evidence envelope |
artifact_structure_only_incoherent |
Loaded structure-only marker is non-bool, co-occurs with a retained value payload, or claims capture_verified=True |
Re-capture and re-save with one current TorchLens version; do not hand-edit the marker, payloads, or the verification verdict |
artifact_tensor_unsupported |
A portable/executable save met a tensor the .tlspec codec cannot store (sparse layout, quantized, nested, meta, DTensor shard, complex32, or a device or dtype outside the codec's list; ArtifactError); the message names the layer and the reason |
Save at level="audit", or make the tensor dense and strided before the save |
artifact_version_above_runtime |
Bundle tlspec_version is newer than this runtime supports |
Upgrade torchlens to the release that wrote the artifact (or newer) |
artifact_version_below_floor |
Artifact was saved by torchlens 2.37 and earlier (tlspec_version < 11, a pickled pre-2.38 module path, or the 2.16 ModelLog format); this release reads only its own format |
Load it with torchlens 2.36.x or 2.37.x, which read it (pip install "torchlens<2.38"), or capture the model again with this release |
metadata_value_unportable |
Trace.save refused before writing: a persisted value has no saved format 3 form at all (a container that contains itself, or a tensor whose payload codec saved format 3 does not write). A value that merely lacks a typed encoding is not refused: it is stringified with a disclosure (manifest disclosures) |
Remove the value from the trace; a TorchLens-written field that trips this is a writer defect -- report it |
bundle_manifest_metadata_mismatch |
manifest.json contradicts the pickled root state: n_layers differs from the persisted op-row count |
Re-save from the source capture; never hand-edit or splice manifest.json / metadata.pkl |
artifact_graph_structure_invalid |
Loaded op rows carry a duplicate/non-string label, a pass stamp outside 1 <= pass_number <= num_passes, or a parents/children entry naming no retained op |
Re-save from the source capture; do not hand-edit op rows or relation lists |
artifact_edge_substitutions_invalid |
A loaded tier-(ii) carrier (Op.graph.edge_substitutions / Op.edge_replacement_stamps) is off-shape, its stamps do not mirror its entries, or an entry's resolve digest / occurrence address is recorded by no intervention audit EDGE or PARAM occurrence row |
Re-apply the intervention on a fresh capture and re-save; do not hand-edit the carriers or the audit |
artifact_annotations_invalid |
A TorchLens-owned annotation family is off-shape at load: non-mapping annotations, logged_values not str-keyed, distributed/collective not a collective_boundary_v1 or functional_collective_boundary_v0 payload (a v0 row must also carry events.event_model == "funcol_issue_is_launch" and a disclosures list), save_mode outside the SaveMode vocabulary, non-int saved_out_version/dedup ids, or a non-mapping varying_across_passes (user keys stay open) |
Re-save from the source capture; TorchLens-owned families are written by capture, never hand-edited |
harvest_address_class_ungated |
Counterfactual-harvest EXECUTION was requested for an address class whose gates (receipt lane + save path + the real 64-image resnet18 workload) no owner has certified (intervened extraction certifies module and type); requests are never silently coarsened to another class (experimental) |
Run the clean policy='none' harvest, or wait for the class gate to be certified |
harvest_schema_invalid |
A tl_counterfactual_harvest_v1 schema violates its closed vocabularies or policy coherence matrix (clean harvests carry no intervention fields; intervened harvests require engine, address class, site-key targets, and the fire receipt digest) (leverage B17; experimental) |
Build the block with HarvestSpec / harvest_block() |
history_artifact_corrupt |
A committed history chunk is missing or fails its recorded sha256, or its index entry names anything but a bare chunk-NNNNNN.npz file in the artifact, or the chunk is a symlink or not a regular file; recovery never silently drops committed data (HistoryArtifactError) |
Restore the chunk from backup or drop the artifact |
history_artifact_budget_exceeded |
The next StepBlock would push the disk history artifact past its byte budget (WatchSettings(artifact_budget_bytes=...), default 256 MiB); refused BEFORE the block, nothing dropped, the artifact readable to the last committed block (HistoryArtifactError) |
Raise artifact_budget_bytes (None disables), raise the cadence, narrow the sites, or drop the sketch tier |
history_artifact_invalid |
History artifact directory misuse: existing manifest at write, unknown format/newer schema at read, or an uncataloged site in a chunk (HistoryArtifactError) |
Write to a fresh directory, read a torchlens.history.v1 artifact, or add_site first |
history_merge_incompatible |
Observation merge across different identities, conflicting scale stamps or presences, or mismatched sketch coverage (HistorySchemaError) |
Merge only observations sharing (step, site, stream, phase) with consistent stamps |
history_ram_budget_exceeded |
The RAM-only history ring is full under the default refuse policy; nothing was dropped or degraded (HistoryArtifactError) |
Attach a disk archive, raise the ring capacity or cadence, or opt into drop_oldest/coarsen explicitly |
history_step_regression |
Duplicate or decreasing global step within one segment (HistorySchemaError) |
Pass strictly increasing steps, or declare a new segment for a resume |
history_vocab_invalid |
A history record field is outside its closed vocabulary, or payload/presence coherence is violated (HistorySchemaError, HistoryArtifactError) |
Use the closed tokens; a non-observed presence carries no payloads |
history_trace_ref_invalid |
A StepBlockRecord.trace_ref is neither None nor a nonempty string (HistorySchemaError); the pointer to a retained Trace is a path or URI |
Pass the retained trace's path or URI as a string, or None when no trace was kept |
observer_event_invalid |
An ObserverEvent violates the event schema: unknown kind/axis, missing kind-specific fields, or a gradient scalar without stage + scale_provenance (ObserverEventError) |
Fix the kind-specific required fields; unavailable needs a reason and 'unknown' is a legal scale |
observer_subscriber_disabled |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): an event-stream subscriber was disabled after consecutive failures reached the limit; collection was never interrupted |
Fix the subscriber and re-subscribe it; failure_counts() carries the per-subscriber tallies |
observer_subscriber_failed |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): an event-stream subscriber raised during publish; collection continues and the subscriber will be disabled after consecutive failures reach the limit |
Fix or unsubscribe the failing subscriber; subscriber bugs never interrupt collection |
profiler_join_op_types_unmatched |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): tl.bridge.profiler.join left op types unmatched because their outermost event count is not a multiple of their layer count or implies a different number of forwards than the other op types; the events are disclosed, never guessed |
Profile whole forward passes only, under one profiler, of the model the trace was captured from |
profiler_session_invalid |
Profiler session argument misuse: borrowed mode without a profiler, owned mode with one, profiler_kwargs on a borrowed session, or an unknown mode/availability token (ProfilerSessionError) |
Fix the session() arguments |
device_time_unavailable |
A device-time column was explicitly requested (hot_path/profile/draw device_time, KernelProfileReport reads) on a capture whose Kineto join did not reach joined -- no joined session, CPU-only session, or failed extraction (ProfilerSessionError) |
Capture through torchlens.report.kernel_profile (owned session) on a CUDA host; on CPU-only hosts host-clock columns are the honest alternative |
decode_style_unknown |
Trace.decode_output(style=...) names a style no built-in or registered custom output detector resolves, or style='hf_text' finds no rank-2 or rank-3 logits (DecodeStyleUnknownError); the message carries a did-you-mean over the built-in styles; custom styles register through tl.postprocessing.register. hf_text without a tokenizer is not a refusal: the rows carry the argmax token_ids and text is None |
Pass classification, imagenet, imagenet1k, or hf_text (tokenizer= turns the ids into text), or register a detector that resolves the style with tl.postprocessing.register(...) |
decode_head_unknown |
Trace.decode_output(head=...) names a head that is not one of the trace's output heads (InvalidArgumentError); fields["available_heads"] lists them |
Pass one of the available heads (output container paths such as logits, 0, 0.logits) |
decode_head_ambiguous |
Trace.decode_output(style=...) found several qualifying output heads and none was named (InvalidArgumentError); fields["available_heads"] lists them |
Pass head= naming one of the available heads |
overhead_arms_invalid |
The paired overhead protocol was invoked with too few measured pairs or negative warmup -- a zero-rep "measurement" is not a measurement (ObservabilityError) |
Use reps >= 3 (11 is the default) and warmup >= 0 |
flops_crosscheck_witness_failed |
The detached FLOP cross-check's two executions produced different outputs, so their dispatch formulas describe different programs and no comparison is honest (CaptureError) |
Run in eval mode or seed the model so both executions follow one program, then re-run tl.report.flops_vs_dispatch |
profiler_session_nested |
A profiler session is already active; there is ONE session engine and ONE activation knob (ProfilerSessionError) |
Close the active session first, or add markers inside it via region() |
region_metadata_invalid |
Span or region metadata carries a non-scalar value (SpanError) |
Pass bool, int, float, or str metadata values only |
sketch_descriptor_invalid |
Histogram grid descriptor with unsupported base, geometry, or encoding (StatKernelError) |
Use base=2, hi_exp > lo_exp, bins_per_octave >= 1, encoding='dense' |
sketch_descriptor_mismatch |
Histogram merge across unequal grid descriptors; there is no rebinning path (StatKernelError) |
Re-accumulate both populations on one shared descriptor |
span_altitude_invalid |
Span altitude outside the closed op / grad_fn_fire / aten set (SpanError) |
Use one of the three altitudes |
span_not_open |
Span close named an id that is not open in the registry (SpanError) |
Close each span exactly once, from the code path that opened it |
span_owner_invalid |
Span owner outside the closed owner classification incl. the mandatory torchlens_internal bucket (SpanError) |
Use a closed owner kind |
stat_dtype_unsupported |
Spine/Histogram reduction over a complex dtype, which has no signed magnitude ordering (StatKernelError) |
Reduce an explicit real view (value.abs() or value.real) and label it |
stat_merge_incompatible |
Spine merge with a non-Spine accumulator (StatKernelError) |
Merge Spine accumulators with Spine accumulators only |
subclass_ctor_under_dispatch_mode_unsupported |
Fast-path or LOGGED-path construction/conversion into a strict torch.Tensor subclass fails under an active TorchLens dispatch mode (completeness witness, intervention-ready capture) on torch 2.1/2.2, where that reconstruction raises "already associated to a python object" (HAS_SUBCLASS_CTOR_IN_DISPATCH_MODE reports False); translate-on-failure, never a preemptive refusal |
Upgrade torch, or avoid constructing/converting into a custom Tensor subclass inside a model forward, an intervention hook, or a validate_forward_pass replay on this build |
trace_option_unsupported |
An explicit Trace option was requested that the resolved backend does not declare, or run() on a trace captured with storage=tl.to_disk(...) (a run would re-capture every payload into RAM while the bundle kept the first capture). An option that cannot compose with chunk_size= has its own code, chunked_capture_option_conflict |
Omit the option, or capture with a backend that declares it; for a streamed trace, capture again with to_disk to a new path or without to_disk and run that trace |
unknown_persisted_field |
Incoming persisted state carries field names outside the reader's declared record contract (fields + defaults + declared aliases); refuses in both writer directions before any object mutation | Load under the release that wrote the artifact and re-save; if it is a governed release artifact, report the refusal |
ambiguous_op_lookup |
Accessor key matches multiple pass-qualified objects | Use a full address, pass label, or call index |
audit_bounds_unknown_name |
tl.debug.param_health(bounds=...) named a tensor absent from the target; unknown names refuse rather than silently skipping (CheckConfigError) |
Use exact qualified names from the target mapping (fix or drop the unknown name) |
audit_within_unknown_name |
tl.debug.param_health(within=...) named a tensor absent from the target; unknown names refuse rather than silently narrowing coverage (CheckConfigError) |
Use exact qualified names from the target mapping (fix or drop the unknown name) |
auto_environment_unsupported |
TORCHLENS_AUTO=1 requested implicit capture |
Unset it and call auto_capture() |
backward_capture_conflict |
save_grads conflicts with backward_ready=False |
Enable or omit backward_ready |
byte_budget_invalid |
A human-unit byte budget (the memory_budget= of tl.neuro.plan_extraction; experimental) is not a positive byte count or a recognized unit string |
Pass an int byte count or a string such as '512 MB' / '8 GiB' |
backward_capture_required |
tl.debug.bisect_nan_backward on a trace with no captured backward pass (experimental) |
Re-trace with CaptureOptions(backward_ready=True, save_grads=...) and run trace.backward(loss) first |
bwd_selector_required |
tl.debug.bisect_nan_backward on a multi-backward trace without bwd= (passes never collapse; experimental) |
Pass bwd=1..N to select one captured pass |
bwd_selector_unknown |
bisect_nan_backward(bwd=N) names a pass that was not captured (experimental) |
Pass one of the captured pass indexes |
backward_ready_conflict |
backward_ready=True conflicts with another capture option or ambient state — disk saves, explicit detaching, active inference mode, or a keep_grad=False default (TrainingModeConfigError, ValueError lineage) |
Drop the conflicting option or drop backward_ready=True |
backward_graph_unavailable |
Backward drawing without a captured backward graph | Call backward(loss) first |
backward_pass_filter_invalid |
Backward pass filter is not a positive one-based int | Pass a positive pass number |
batch_items_invalid |
Export batch-items count is negative | Pass a non-negative integer |
batchnorm_train_stats_mutated |
WARNING (not a refusal): a CaptureOptions(carry_state=True) capture ran the real forward and train-mode norm layers advanced their running statistics in place (the default pure-observer capture restores them); once per process |
drop carry_state=True for an observational capture; training-through-trace users ignore |
capture_state_restore_incomplete |
WARNING (not a refusal): a default (pure-observer) capture could not restore every piece of model state it observed; the named items keep the values the traced forward left | re-load the affected state before relying on the model, or pass CaptureOptions(carry_state=True) |
failed_capture_release_incomplete |
WARNING (not a refusal): TorchLens could not fully release its preparation of the model after a failed capture; module metadata and prepared-model bookkeeping may stay registered (every submodule forward is already back) |
Call tl.release_model(model) once the underlying condition is resolved |
held_tensor_scan_truncated |
WARNING (not a refusal): the module-held plain-tensor scan found a plain tensor past its depth or object bound, or ended at its 65536-item cost cap with items left unexamined; a tensor past the cut that the forward reads has no buffer source and the graph shows the read without it; forward validation of the capture fails (source_provenance check) |
Register the tensor with register_buffer, or hold it in a shallower or smaller container |
batch_render_invalid |
Batch render policy is unknown or malformed | Choose a documented batch_render policy |
bind_cleanup_failed |
Bound-call runtime teardown failed after the call; the base model may retain TorchLens hooks (BindingRuntimeError; capture-free lane, experimental) |
Drop the binding, remove leftover forward hooks or re-instantiate the model, and rebuild the binding from the immutable spec |
bind_generate_unavailable |
binding.generate(...) on a base model with no callable generate; the binding holds the runtime across a real HF generate and never invents one (experimental) |
Call the binding directly (bound(x)), or wrap your own generation loop around it |
bind_lazy_output |
A bound call (binding.generate(...) or bound(x)) returned an async lazy output (async generator, async iterator, coroutine or other awaitable), whose forwards would run inside an event loop where the binding cannot keep its edits scoped to them. A synchronous generator or iterator from a plain bound call is supported: every step runs armed and the report settles on exhaustion, close() or an exception (BindingRuntimeError; experimental) |
Return a synchronous generator or an eager value; use spec.bind(model).generate(...) and iterate it |
bind_model_invalid |
spec.bind(model) operand is not an nn.Module (bound methods have their own root contract), or is itself a bound intervention executor — bindings never nest (BindingPreflightError; experimental) |
Pass the plain base nn.Module; for a binding operand, bind binding.model after merging specs explicitly |
bind_rule_runtime_error |
A rule's WHERE evaluation raised at a live op during a bound call, for example a user predicate or a tl.where reading a post-capture field such as p.layer_label (BindingRuntimeError; the user exception is chained; experimental) |
Fix the predicate/selector to tolerate live capture contexts, or re-express the WHERE term structurally |
bind_rule_unsupported |
A rule carries no executable hook payload, edits gradients (the capture-free lane replaces forward values only, so lowering a gradient edit would edit the activation instead), or composes a module OUTPUT-boundary term (tl.module) with op-level terms other than at_step(...) decode-step qualifiers, which the capture-free lane cannot evaluate at one site, or selects with a term only a capture can match (a final, short or pass-qualified label in tl.label/tl.label_contains/tl.label_matches, or tl.followed_by/tl.preceded_by/tl.model_input, negated or combined), refused when bound before any forward (BindingPreflightError; experimental) |
Use a value-replacing action; edit gradients on a backward_ready trace with trace.backward(loss); use plain tl.module(address) (optionally & at_step(...)) for boundary edits or tl.in_module(address) for op-level containment; select a labelled op structurally with tl.func(<op type>) & tl.in_module(<address>) |
helper_tensor_changed_since_capture |
A tensor held by a staged helper (tl.steer, tl.mean_ablate, tl.project_onto, tl.project_out and torchlens.intervention._helpers.swap_with keep the caller's tensor by reference) changed since the entry was staged (full-content digest, so .data writes count). Raised only by a legacy rerun (plain, append, chunked; trace unchanged) and by save_intervention (nothing written), both SpecMutationError. A bound executor never raises it: it reads the helper's tensor at each call, in-place changes apply to the next call, and BindReport.helper_tensor_versions records the version counters. Experimental. |
Re-stage the edit (remove it with clear_edits(site) and stage it again with do, or capture fresh), or restore the tensor's value |
bind_spec_empty |
bind() on a spec with zero rules: zero fires by construction (experimental) |
Add at least one tl.when(...) clause before binding |
bind_spec_invalid |
bind() engine received something other than the immutable public Recipe (experimental) |
Build the spec with tl.when(...) and call spec.bind(model) |
bind_static_anchor_unresolved |
A rule's static module-address anchor names no module on the base model, checked at bind time before ANY forward. An ALIAS spelling of a shared module (self.dec = self.enc: tl.module("dec"), tl.module("dec:2"), tl.in_module("dec"), tl.in_module("dec:2"), tl.site(module_path="dec"), alone or under & / \| / ~) refuses with this code and ONE message at EVERY door: tl.trace and tl.record intervene= / save= / stop_after= before the forward, post-hoc find_sites / resolve_sites / fork().do, and spec.bind. No hook can tell which name a forward called the object through, so an alias would edit every call site; the message names the canonical named_modules() name, which fires at every call site of the shared module, and Module.all_addresses / BindReport.module_aliases disclose the alias map (BindingPreflightError; experimental) |
Fix the address to a name in model.named_modules() (the canonical name fires at every call site of a shared module; a pass label such as "enc:2" selects one call), or drop the stale rule |
bridge_pass_index_invalid |
tl.bridge.captum.layer got a pass_index= that is not a positive integer or is past the last pass, or the site names several passes and pass_index= is missing (InvalidArgumentError) |
Pass the 1-based call or pass index, such as pass_index=2, or the pass-qualified label |
bridge_pass_index_needs_module_address |
tl.bridge.captum.layer got pass_index= with a single-pass site that is not a plain module address of the source model (an op label or "address:pass" spelling already names one call) (InvalidArgumentError) |
Pass a module address such as "layer4.1.relu" with pass_index=, or the op label or "address:pass" spelling alone |
bridge_captum_multi_probe_unsupported |
tl.bridge.captum.attribute got a Captum method whose layer list holds more than one TorchLens site probe; one spliced forward serves one probe (InvalidArgumentError) |
Attribute each spliced site with its own method object |
bridge_captum_site_not_reached |
The forward tl.bridge.captum.attribute ran for a spliced site probe executed the probe's site fewer times than the probe's call ordinal (inputs that take another path than the trace the site was picked from), so Captum's hook never saw the tensor (InvalidArgumentError) |
Attribute with inputs that take the same path as the originating trace, or pick a site on the path these inputs take |
bridge_module_site_unresolved |
tl.bridge.pytorch_grad_cam.layer/cam was given a site that is not the output of any module of the source model (an input placeholder, a free function op), so there is no module to hook (InvalidArgumentError; tl.bridge.captum.layer serves such a site with a spliced probe instead) |
Pass a module address such as "layer4", or the label of an op whose tensor a module returns |
bridge_module_site_ambiguous |
The site's tensor is the output of two sibling modules at the same outermost depth (for example consecutive identity modules), so no one module owns it (InvalidArgumentError, raised by tl.bridge.pytorch_grad_cam; tl.bridge.captum.layer serves the site with a spliced probe) |
Pass one of the named module addresses directly |
bridge_module_site_multi_call |
The site resolves to a module that runs more than once in the trace (an op label, or a pass-qualified address such as "layer4.1.relu:1", each resolved to the outermost module whose output the site's tensor is); a module hook would see every call, not the one the site names (InvalidArgumentError, raised by tl.bridge.pytorch_grad_cam; tl.bridge.captum.layer serves the one call with a spliced probe) |
Pick a site whose outermost owning module runs once, or pass the address of an enclosing module that runs once (the remedy names the nearest one; it returns its own output, not this tensor) |
sae_splice_tokens_mismatch |
tl.bridge.sae.splice(..., tokens=...) got tokens that are not an integer tensor, or no model output is shaped tokens.shape + (vocab,), so there are no next-token logits to score (InvalidArgumentError; experimental) |
Pass the integer token ids the model ran on (for a Hugging Face causal LM, the input_ids), shaped like the logits without their vocabulary axis |
sae_splice_bos_needs_sequence_axis |
tl.bridge.sae.splice(..., exclude_bos=True) at a site that is not (batch, sequence, features) with at least two positions, so there is no BOS position to leave out (InvalidArgumentError; experimental) |
Drop exclude_bos=True for sites without a sequence axis, or splice a token-level site |
keep_grad_replay_frontier |
WARNING: tl.intervention.keep_grad(edit) fired under differentiable replay (do(site, edit, intervention=InterventionOptions(differentiable=True))): the edit keeps the graph, but the replay frontier re-enters the edited value as a fresh leaf, so no parameter upstream of the site gets a gradient; once per session |
Run the edit on a live forward: tl.when(tl.module(name), tl.intervention.keep_grad(edit)).bind(model)(x) or tl.trace(model, x, intervene=tl.when(tl.module(name), edit)) |
sae_splice_logged_needs_live_model |
tl.bridge.sae.splice(trace, ..., log_latents=True): the logged splice captures the live model again with the SAE inside it, so a Trace door has no inputs to run (InvalidArgumentError; experimental) |
Call splice(model, inputs, site=..., sae=..., log_latents=True) with the live model |
sae_splice_logged_output_not_tensor |
splice(..., log_latents=True) at a site whose owning module returns a non-tensor, so its output cannot be replaced by the reconstruction (InvalidArgumentError; experimental) |
Splice without log_latents=True, or at a site a module returns as a tensor |
sae_family_name_invalid |
tl.bridge.sae.register(name, ...) with an empty name or one holding brackets, commas or whitespace, which the latent facet spelling name[k] reserves (InvalidArgumentError; experimental) |
Register under a plain name, e.g. register('res', sae, site=...) |
sae_family_name_taken |
tl.bridge.sae.register(name, ...) under a name already registered (InvalidArgumentError; experimental) |
tl.bridge.sae.unregister(name) first, or register under a new name |
sae_family_unknown |
tl.bridge.sae.unregister(name) for a name nothing is registered under (InvalidArgumentError; experimental) |
Unregister a registered name |
sae_latent_family_unknown |
tl.facet(name).latent(k) where no SAE is registered as name; the message lists the registered names (InvalidArgumentError; experimental) |
tl.bridge.sae.register(name, sae, site=...) first, or use a registered name |
sae_latent_index_invalid |
tl.facet(name).latent(index) with an index that is not a non-negative int or a non-empty list of them (InvalidArgumentError; experimental) |
Pass an int or a list of ints, e.g. latent(0) |
sae_latent_index_unknown |
tl.facet(name).latent(k) (or facets[f"{name}[{k}]"]) where the SAE has no latent k; the message gives the SAE's latent count (InvalidArgumentError; experimental) |
Name a latent from 0 to the count minus one (the message spells the last) |
sae_latent_site_ambiguous |
The SAE was registered at a string site that does not name exactly one op of a layer that runs once in this trace, so one latent spelling would edit more than one place (InvalidArgumentError; experimental) |
Edit one pass through the splice door, tl.bridge.sae.splice(model, inputs, site=<one pass>, sae=sae, latents_edit=fn), with the pass label from the error's one_pass_site field; or re-register at a selector to edit every pass or match, e.g. register(name, sae, site=tl.module('fc1')) |
sae_latent_site_unmatched |
The SAE was registered at a selector site that matches no op of this trace (a trace of another model, say), so its latents have no home here (InvalidArgumentError; experimental) |
Read and edit the latents on a trace of the model the SAE was registered for, or register it at a site this model has |
sae_splice_latents_large |
WARNING: the SAE latents tl.bridge.sae.splice keeps in SpliceResult.latents (and edited_latents) pass 256 MiB; every latent is kept; once per session |
splice(..., keep_latents=False), then encode only what you read with sae.encode(result.clean_site_out[...]) |
sae_splice_zero_variance |
WARNING: the clean splice-site activation has zero total variance, or no feature dimension varies across its tokens (one token), so a fraction of variance explained is nan and SpliceResult.zero_variance is True; the reason is in unavailable_metrics; once per session |
Splice a batch of several distinct inputs, or a multi-token sequence |
sae_export_tokens_invalid |
tl.bridge.sae.write_delphi / write_sae_dashboard got token ids that are not an integer [examples, sequence] tensor, that do not match dense latents' [examples, sequence], or that a dataset top-k names an example or position outside of (InvalidArgumentError; experimental) |
Pass the input_ids the model ran on, one row per example, in the order the latents or tl.stats.aggregate saw them |
sae_export_latents_invalid |
tl.bridge.sae.write_delphi / write_sae_dashboard got latents that are neither a dense [examples, sequence, latents] (or [examples, latents]) tensor nor a tl.stats.TopK(..., unit_axis=-1) result with at most one position axis, or latent_ids= names a latent out of range (InvalidArgumentError; experimental) |
Pass SpliceResult.latents, sae.encode(activations), or the UnitTopK of tl.stats.TopK(k, unit_axis=-1, encoder=sae.encode) over a token-level site; latent_ids in range(latents) |
sae_export_dashboard_large |
WARNING: the JSON tl.bridge.sae.write_sae_dashboard writes is estimated above 256 MiB; every requested latent is written; once per session |
write_sae_dashboard(..., latent_ids=[...]) for the latents you will open, or a smaller k= |
hf_attention_registry_unavailable |
tl.bridge.transformers.register_attention needs transformers with both the AttentionInterface and the AttentionMaskInterface registries; registering the attention function without its mask function is the mask trap, so the backend refuses instead (MissingDependencyError; experimental) |
Install transformers>=4.53 |
hf_attention_key_taken |
The "torchlens" attention or mask key is already registered to a non-TorchLens function; the backend never overwrites a foreign registration and never registers over a built-in key (InvalidArgumentError) |
Remove the foreign "torchlens" registration first |
hf_attention_backend_not_selected |
tl.bridge.transformers.record_attention(model) on a model whose config._attn_implementation is not "torchlens", so the recording would stay silently empty (InvalidArgumentError) |
Call tl.bridge.transformers.register_attention(model) or load with attn_implementation="torchlens" |
hf_attention_multiple_calls |
recording[name] on an attention module called more than once in the recording (generation steps, reused blocks) (InvalidArgumentError) |
Read every call with recording.calls_for(name) |
hf_attention_kwarg_unsupported |
The TorchLens attention backend was called with a sparse-index or packed-sequence kwarg (indices, block_indices, cu_seq_lens_q, cu_seq_lens_k) whose math it does not implement (InvalidArgumentError) |
Load the model with attn_implementation="eager" or "sdpa" |
hf_attention_sdpa_mismatch |
record_attention(model, check_sdpa=True): one call's output disagrees with scaled_dot_product_attention on the same inputs beyond the semantic SDPA reconstruction tolerance (ValidationError) |
Report the model; compare against attn_implementation="eager" |
structure_only_text_mask_not_all_ones |
Structure-only text capture (tl.trace(meta_lm, "text", capture=CaptureOptions(structure_only=True)) or tl.bridge.transformers.trace_text) builds a meta all-ones attention mask, but the tokenized prompts are padded, so their mask pattern would be lost (InvalidArgumentError) |
Trace one prompt, or prompts of equal token length, at a time |
bridge_shap_background_missing |
tl.bridge.shap.explain got background=None; SHAP values are relative to a background's expected output and there is no default (InvalidArgumentError) |
Pass background= a batch of reference inputs shaped like the model input |
direction_method_unknown |
torchlens.intervention.fit_direction got a method= other than "mean_diff", "pca" or "logistic" (InvalidArgumentError) |
Pass one of the methods named in the message |
direction_pairs_empty |
fit_direction got an empty sequence of positive or negative traces (InvalidArgumentError) |
Pass at least one trace per side |
direction_pairs_mismatch |
fit_direction read positive and negative rows that do not pair up (a different number of prompts or hidden sizes, or traces of one side read at different widths) (InvalidArgumentError) |
Trace one negative prompt per positive prompt with the same model, reading one token each |
direction_pairs_identical |
fit_direction read identical positive and negative rows, so the direction would be all zeros (typically the positive traces passed twice) (InvalidArgumentError) |
Check that neg_traces holds the negative prompts |
direction_site_unsaved |
fit_direction resolved the site in a trace that saved no tensor out there (InvalidArgumentError) |
Trace with the site saved (for example layers_to_save="all") |
direction_read_token_rank |
fit_direction got a read_token_index for an activation that is not [n_prompts, n_tokens, hidden] (InvalidArgumentError) |
Pass read_token_index=None for outs that are already one row per prompt |
direction_read_token_count |
A per-prompt read_token_index list given to fit_direction has a different length from the number of prompts on one side (InvalidArgumentError) |
Pass one int for every prompt, or one position per prompt |
direction_mask_shape |
A trace's saved attention_mask input does not match the activation's [n_prompts, n_tokens] in fit_direction (InvalidArgumentError) |
Trace the prompts with the attention mask they were tokenized with |
direction_mask_empty_row |
A prompt's saved attention mask has no unmasked token, so fit_direction can read no token (InvalidArgumentError) |
Drop empty prompts before tracing |
direction_logistic_unconverged |
fit_direction(method="logistic") did not converge within its Newton step limit (InvalidArgumentError) |
Use method="mean_diff" or "pca", or check the rows for non-finite values |
direction_layer_unknown |
Direction.to_steering_vectors, Direction.to_repeng, Direction.to_dialz or Direction.library_layer found no trailing layer index in the site label and no integer layer= was given (InvalidArgumentError) |
Pass layer= (the decoder block the library should patch) |
direction_layer_mismatch |
A converter got layer= different from the layer index the direction's site names, so the library would patch another block (InvalidArgumentError) |
Omit layer= to patch the layer the direction was read at |
direction_model_type_unknown |
Direction.to_repeng or Direction.to_dialz found no recorded model_type on the direction and none was given (InvalidArgumentError) |
Pass model_type= (for example 'llama') |
bridge_depyf_prepare_debug_missing |
tl.bridge.depyf.dump found an installed depyf without prepare_debug (CaptureNotActiveError, RuntimeError lineage) |
Install depyf>=0.18 (pip install "torchlens[depyf]") |
bridge_depyf_nothing_dumped |
tl.bridge.depyf.dump ran torch.compile under depyf.prepare_debug but no file was written, because Dynamo reused a cached compile of the model (CaptureNotActiveError, RuntimeError lineage) |
Call torch._dynamo.reset() before dump() to force a fresh compile |
bridge_captum_inputs_unresolved |
tl.bridge.captum.attribute was called without inputs= and the logged inputs cannot be replayed positionally: an input was passed by keyword only or inside a container, was not saved, or a positional parameter between two logged inputs has no tensor (InvalidArgumentError); the bridge never drops an input silently (experimental) |
Pass inputs= explicitly (a tensor or a tuple of the positional tensors) and the rest through Captum's additional_forward_args= |
bridge_inseq_method_unknown |
tl.bridge.inseq.attribute got a method= that is neither an inseq identifier nor a TorchLens spelling of one (InvalidArgumentError; experimental) |
Use a name from inseq.list_feature_attribution_methods(); the remedy lists them |
bridge_inseq_forced_decoding_ignored |
tl.bridge.inseq.attribute(..., generated_texts=...) returned an attribution of a different text than the one requested; inseq reports an ignored keyword only in its log, so the bridge compares the attributed text itself (InvalidArgumentError; experimental) |
Check that the attribution model supports forced decoding and that every keyword is spelled as inseq's attribute() names it |
bridge_gradcam_call_option_conflict |
tl.bridge.pytorch_grad_cam.cam got the same CAM call option both in call_kwargs= and as a keyword (KeywordConflictError; experimental) |
Give each call option once, preferably in call_kwargs= |
hub_push_artifact_unsupported |
tl.bridge.huggingface_hub.push_to_hub got an object that is neither a Trace nor a Bundle; Hub uploads are always a portable .tlspec bundle and never a raw pickle (ArgumentTypeError; experimental) |
Push a Trace or Bundle; save an intervention recipe with torchlens.io.save_intervention and share that directory |
hub_artifact_unsafe |
tl.bridge.huggingface_hub.from_hub downloaded a file that is not a readable gzipped tar, or a tar member is a link or special file, has an absolute or parent-escaping name, sits outside the one top-level bundle directory, or the archive exceeds its member or size bound (ArtifactError; experimental) |
Point path_in_repo at an artifact uploaded with push_to_hub, or download and inspect the file before loading it with tl.load |
tracker_mlflow_run_id_missing |
tl.export.mlflow got an MlflowClient-style client (log_metric(run_id, key, value)) without run_id= (ArgumentTypeError) |
Pass run_id=run.info.run_id, or pass the fluent mlflow module to log into the active run |
tracker_mlflow_run_id_without_client |
tl.export.mlflow got run_id= without a client= to log through (KeywordConflictError) |
Pass client=mlflow.MlflowClient() with run_id=, or drop run_id= |
tracker_mlflow_run_id_unsupported |
tl.export.mlflow got run_id= for a client whose log_metric takes no run id (KeywordConflictError) |
Drop run_id=, or pass an mlflow.MlflowClient |
bind_zero_fire |
One or more rules never fired during a bound call and the binding was made with on_zero_fire='error'; the full report is retained on .last_report (BindingRuntimeError; under the default 'warn' the same code is a warning; experimental) |
Fix the WHERE terms so every rule fires, or bind with the default on_zero_fire='warn' or 'disclose' |
unwrapped_op_in_capture |
The capture ran an operation the backend's wrappers do not cover, so the trace cannot be complete (mlx) | Restrict the model to the backend's wrapped ops, or capture with the PyTorch backend |
runtime_mode_unsupported |
Paddle runs outside dygraph mode, or in PIR mode, so eager capture has no ops to record (paddle) | Capture in dygraph mode with PIR disabled |
inplace_op_unsupported |
An in-place or global-state Paddle op ran inside the forward; the preview cannot record a mutation as a graph edge (paddle) | Use the out-of-place op in the forward, or capture with the PyTorch backend |
input_mutation_unsupported |
The traced callable mutated an input with Tensor.assign(), Tensor.replace() or setitem (tinygrad) |
Return a pure lazy tinygrad expression instead of mutating inputs |
tensor_output_required |
The traced callable returned no tinygrad Tensor (tinygrad) | Return at least one tinygrad Tensor from the traced callable |
tinygrad_input_required |
No positional input of the call is a tinygrad Tensor (tinygrad) | Pass the inputs positionally as tinygrad Tensors |
live_payloads_required |
Replay validation or derived gradients were requested on an audit-only trace, which keeps no live realized-copy payloads (tinygrad) | Capture with live DEV=PYTHON realized-copy payloads before validating or deriving gradients |
mid_capture_execution_unsupported |
The traced callable realized a tensor or ran a TinyJit function during capture (tinygrad) |
Return a lazy tinygrad expression; realize or JIT outside the traced callable |
traced_transform_entry_unsupported |
The capture entry is an mx.compile, mx.grad or mx.vmap wrapper, whose replays bypass the eager capture surface (mlx) |
Trace the eager mlx.nn.Module or plain callable instead of its compiled or transformed wrapper |
intervention_with_derived_grads_unsupported |
grad_options= was combined with intervene= or stop_after= in one call; the derived-gradient replay re-runs the model without the intervention (mlx) |
Capture the intervened trace and the derived gradients in separate calls |
intervention_result_invalid |
An intervention returned something other than an mx.array, or changed the output's shape or dtype (mlx) |
Return an mx.array with the same shape and dtype as the hooked output |
validation_replay_unsupported |
validate= replay was requested on a backend that declares no replay validation |
Capture with validate=False, or use a backend that declares has_validation_replay |
validation_scope_invalid |
validate(scope=...) named an unknown scope, or passed num_threads= / trace_observer= with a scope other than "forward" or "saved" (fields["keyword"] names it) |
Pass one of the scopes the message lists, or omit the keyword |
validation_status_has_no_truth_value_before_run |
A ValidationStatus was used as a boolean before replay validation ran |
Read status.state, or run replay validation first |
viz_array_shape_invalid |
A plotting primitive got an array of the wrong shape | Pass the shape the message names |
viz_images_too_few |
image_scatter got fewer images than points it draws |
Pass enough images or lower max_items |
viz_input_empty |
A plotting primitive got nothing to draw | Pass at least one item |
viz_limit_invalid |
A plotting size or count limit is below its minimum | Pass the minimum the message names or more |
viz_values_not_finite |
A plotting primitive got no finite values to draw | Replace or drop NaN and infinite values |
zero_fire_policy_invalid |
on_zero_fire is outside the closed warn/error/disclose vocabulary, at any door (spec.bind / binding.generate(...), tl.trace, Trace.run; InvalidArgumentError; experimental) |
Pass on_zero_fire='warn' (default), 'error' or 'disclose' |
trace_zero_fire |
A capture-time intervene= (or one of its rules) fired at zero sites and the capture ran with on_zero_fire='error'; under the default 'warn' the same code is a warning (SiteResolutionError; experimental). A tl.module target whose recorded output is not a tensor adds fields["reason"] == "module_output_not_tensor" and a reason_detail naming the output type and, for a torch.distributions output, its parameter output paths; rerun_zero_fire, bind_zero_fire and the fast rerun's fast_rerun_graph_unsteered carry the same fields |
Fix the intervene= selector so it matches a site, or capture with the default on_zero_fire='warn' or 'disclose' |
binding_reentrant_call |
A bound intervention executor was called while already executing; v1 bindings are serial and non-reentrant, and an open lazy generate output holds the binding until it is exhausted or closed (BindingRuntimeError; experimental) |
Wait for the active call to return (exhaust or close() an open lazy output), or build separate bindings from the same immutable spec |
binding_serialization_unsupported |
Pickle/copy of a bound intervention executor; the spec is the keepable artifact and the binding is cheap to reconstruct (one save path, one trust gate; experimental) | Save the spec through the intervention-spec save path and rebuild with spec.bind(model) after loading |
binding_training_surface |
Module-like attribute access (parameters, state_dict, to, train, ...) on a bound intervention executor, which is NOT an nn.Module and never will be (teaching refusal; experimental) |
Write a small wrapper nn.Module you own around binding.model, or use the base model directly |
backend_ambiguity |
Auto-resolution found multiple equal backend matches | Pass backend= explicitly |
backend_capability_conformance |
Advertised backend capability has no implementation (BackendCapabilityConformanceError, dual ValueError + NotImplementedError lineage) |
Disable it or register its implementation |
backend_error |
Base-class default of the backend registry family — never raised directly; every live registry refusal carries one of the specific backend_*/unknown_backend codes below |
Branch on the specific backend codes; this row exists only so an unmigrated future subclass is still documented |
backend_maturity_invalid |
A BackendSpec declares a maturity label outside the closed set (preview, stable); BackendRegistryError at registration |
Register the spec with maturity preview or stable |
backend_mismatch |
Explicit backend cannot handle the model or inputs | Select the owning backend |
bundle_draw_graph_invalid |
Bundle.draw(graph=) is not one of forward, backward, combined or diff |
Pass one of the four graph names |
bundle_draw_keyword_unsupported |
Bundle.draw got a keyword the bundle renderer does not support yet (a Trace.draw keyword such as depth= or vis_mode=, or a removed spelling such as signal=); ArgumentTypeError naming the supported list |
Use the keywords Bundle.draw lists (graph= replaces signal=); draw one member with bundle[name].draw(...) for the other Trace.draw keywords |
bundle_show_kind_invalid |
Bundle.show(kind=) is not None, graph, strip, repr or html |
Pass kind=None (the merged graph) or one of the four kind names |
draw_format_mismatch |
Trace.draw or Bundle.draw got a path whose extension names one format and a file_format= naming another (ArgumentConflictError) |
Drop file_format= (the extension picks the format), or end the path with the extension of the format you want |
bundle_load_failed |
Bundle load failed on torch/codec drift or a missing dependency (a manifest whose blob files are gone has its own code, bundle_blob_missing) |
Inspect the chained cause; restore the missing dependency or re-save |
bundle_blob_missing |
tl.load on a bundle whose manifest names blob files that are absent on disk (the saved format 3 reader's file-table check for a listed blobs/ chunk, unified-trace preflight and manifest blob-path validation); the load stops before any payload is read |
Restore the missing blob files, or re-save the bundle from its source capture |
bundle_metadata_integrity_refused |
Bundle metadata pickle is denylisted, corrupt, or truncated | Treat as tamper/corruption; re-save from the source capture |
bundle_producer_unverifiable |
Current-schema bundle's recorded torchlens_version does not parse under PEP 440 |
Re-save the artifact with a released torchlens |
bundle_torch_incompatible |
Bundle's recorded torch version is major-incompatible with (or unparseable against) the runtime torch | Load under a torch runtime with the recorded major version |
bundle_save_failed |
Bundle save failed; the staging dir was marked PARTIAL and any pre-overwrite bundle restored (an existing target has its own code, bundle_path_exists) |
Fix the chained cause named in the message and re-save |
bundle_path_exists |
The save target already exists: a to_disk path, or a Trace.save / Bundle.save path without overwrite=True (checked at entry and again at publish time, so a concurrent writer that publishes mid-save is refused rather than destroyed); the existing bundle is left in place |
Pass overwrite=True to replace the existing bundle (Trace.save, Bundle.save), or save or stream to a path that does not exist yet |
bundle_save_option_unsupported |
bundle.save(path, ...) received a per-trace payload option; the Bundle container door supports only level and overwrite |
Drop the option (or use bundle.save); save one member with trace.save(bundle[name], ...) for per-member payload control |
bundle_member_has_relations |
A Bundle mutator (remove/clear/eviction) would orphan member-relation rows — silent orphaning is forbidden | Pass cascade_relations=True to drop the rows explicitly, or remove the relations first |
bundle_relation_member_missing |
A member-relation row names a member absent from the Bundle (no dangling edges, ever) | Add the named member or drop the row |
bundle_relation_schema_invalid |
A member-relation row is outside the closed schema (unknown kind, wrong row shape for the kind, or undeclared/missing-required params — grammar v2's required/optional split included; the amendment), a relation kind the artifact's stamped tlspec version does not admit (fed_by or selected_by before 10), or token_spans="auto" off its one spelling (a fed_by pair row without basis or coverage) |
Use the documented relation kinds and their declared params |
bundle_relation_evidence_over_budget |
A successor_of evidence envelope crosses the per-row canonical-JSON byte budget (1 MiB, the sidecar family default) |
Store digests/references in the envelope and move bulk payloads to a sidecar family |
bundle_relation_auto_spans_unavailable |
Bundle.relate("fed_by", later, earlier, token_spans="auto") lacks its evidence: the source binding names no completion range, the reader carries no binding, or a member's token ids are not retained |
Attach a token_boundary_v1 descriptor with the source's completion (torchlens.io.attach_sidecar), keep the token-id inputs saved, or declare token_spans rows |
bundle_relation_auto_spans_ambiguous |
token_spans="auto" found several placements of a source run in the reader's prompt (a repeated quote, or a tie between two trims), or two runs on the same reader tokens |
Declare the spans as [src_start, src_end, dst_start, dst_end] rows |
bundle_relation_auto_spans_unmatched |
token_spans="auto" found no run of the source's eligible output in the reader's prompt, even with up to two boundary tokens trimmed per side |
Check the source's bound completion range; declare the spans for retokenized or paraphrased text |
bundle_relation_span_out_of_bounds |
A fed_by token_spans row reaches past the source or destination member's token stream (its bound token_boundary_v1 length, else its first integer input's sequence length); fields["side"] names which |
Index the stream the coordinates really index, or bind that stream before relating |
bundle_relation_span_unverified |
A fed_by row claims basis="verified" or "matched" but its evidence contradicts it: a member binding's digest disagrees with the retained token ids, a source span leaves the bound completion, or the token ids differ span by span (re-checked at relate, construction and load, and by Bundle.token_pairs at read) |
Drop the claimed basis so the row records a declaration, or fix the spans or bindings |
bundle_token_divergence_unavailable |
Bundle.token_divergence (or a pairing inside Bundle.add_alternative) cannot split a member into prompt and completion: it carries no token_boundary_v1 binding, the binding names no completion range, or its token ids are not retained or disagree with the binding; fields["member"] and fields["reason"] say which |
Attach a binding naming the member's completion range (torchlens.io.attach_sidecar) and keep the token-id input saved |
alternative_target_missing |
A call named in Bundle.add_alternative(..., steered=...) is not a member of the original run or of the second run; fields["side"] says which |
Name each steered call as the harness names its member in both runs |
alternative_target_unsteered |
A declared steered call of the second run was captured without an intervention spec that fired | Capture the steered call with tl.trace(model, ids, intervene=spec), the spec it generated under |
alternative_steer_undeclared |
A second-run call not declared in steered= was captured under an intervention spec |
Declare every steered call, or capture the others plainly |
alternative_capture_position_dependent |
A declared steered call's spec edits chosen token positions or decode steps (at_positions, at_step): one teacher-forced forward does not reproduce that generation |
Use a position-uniform spec, or capture the generation as an episode |
alternative_member_name_taken |
A second-run copy (prefix + name) would reuse an existing member name |
Pass another prefix= |
alternative_unchanged_call_diverged |
An unsteered call saw the same prompt in both runs but its completion differs: the runs carry noise TorchLens cannot separate from the steer's effect; nothing is added | Seed each call (not once per harness), use deterministic algorithms and keep the batch the same |
bundle_relation_unknown_kinds_opaque |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): unknown namespaced relation kinds loaded opaque under the preserve-and-disclose doctrine |
Load with the owning provider, or pass unknown_relations='refuse' |
bundle_unknown_sections_preserved |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): unknown namespaced bundle.json sections preserved opaque through the Bundle carriage |
Load with the owning provider to consume them, or ignore the disclosure |
bundle_section_unknown |
bundle.json carries an unknown BARE top-level section — writer-owned sections are bare, extension sections are namespaced <ns>.<name> (which load opaque and re-save verbatim); the historical silent load-then-destroy is banned in both directions (C07X loader doctrine leg (c)) |
Namespace the section (myorg.index), or repair the drifted artifact |
unknown_relations_policy_invalid |
tl.load(unknown_relations=...) received something other than 'opaque' or 'refuse' |
Pass unknown_relations='opaque' (preserve-and-disclose) or 'refuse' |
bundle_member_type_invalid |
A Bundle membership door (constructor / add) received a non-capture value — members are Trace or PartialTrace objects; an experiment container with unvalidated membership cannot carry a provenance join (a dict once became member_3) |
Pass Trace objects (live, loaded, or failed-partial); keep other values outside the bundle |
bundle_lineage_invalid |
A persisted Bundle lineage surface is off-shape or chain-broken: a member_construction anchor with undeclared keys / unknown origin / a non-member name, or a bundle_operation_v1 row whose seq/prev-digest chain does not re-derive (the operation ledger is append-only and hash-chained) |
Repair the drifted artifact; anchors carry only declared keys over the closed origin vocabulary, and operation rows are never edited or reordered |
sweep_baseline_name_collision |
tl.sweep(include_baseline=True) reserves the member name baseline for the pristine capture, but names= also carries baseline |
Rename the swept member, or drop include_baseline |
provenance_reference_missing |
bundle.why(member) needs a reference and this bundle has no baseline |
Set baseline= at construction, or pass relative_to=<member> |
provenance_self_comparison |
bundle.why(member, relative_to=member) compares a member against itself — vacuous |
Pass a different relative_to= member |
vary_mapping_invalid |
bundle.vary() received something other than a mapping of member -> Recipe / (selection, edit) / None, or an unmentioned= value other than 'unchanged' (do broadcasts one edit; vary names one edit or identity per member) |
Pass one spec, sugar pair, or explicit None per member |
vary_member_unknown |
bundle.vary() mapping names a non-member (typed preflight before any mutation) |
Name current members only |
vary_member_duplicate |
bundle.vary() mapping names one member more than once after normalization |
One explicit edit or identity per member |
vary_coverage_incomplete |
bundle.vary() mapping omits members and unmentioned='unchanged' was not passed — a silently unedited member reads as a null result |
Name every member (None = explicit identity), or pass unmentioned='unchanged' |
vary_partial_failure |
A bundle.vary() member application failed mid-apply; NO rollback is claimed — completed members keep their edits, the per-member outcomes ride the operation chronology, and the exception fields carry material_action_completed=True with the original failure chained |
Inspect fields['outcomes'], repair the failing spec, and re-vary the unstarted members |
retention_projection_over_budget |
A sweep/engine retention projection (lower-bound basis: current retained bytes + per-candidate cost x retained candidates) crosses the byte ceiling — refused BEFORE the first candidate runs (the shipped accountant is per-capture, so only this bundle-level projection can price what a sweep destroys or retains) | Retain fewer members (retain=top_k(k) or 'none'), raise the ceiling, or use the cheaper replay lane |
site_sweep_candidates_invalid |
sweep_sites candidates= is not a mapping/sequence, is empty, or names the reserved baseline member |
Pass an ordered candidate plan; rename the colliding candidate |
site_sweep_engine_invalid |
sweep_sites engine= is outside the closed lane vocabulary (live_hook / replay); the lane is stamped in every envelope, never guessed |
Pass a documented lane |
site_sweep_metric_invalid |
sweep_sites metric= is missing, not callable, or returned a non-finite value — the metric IS the experiment and has no default |
Pass callable(member_trace) -> finite real scalar |
site_sweep_retain_invalid |
sweep_sites retain= is missing or outside 'all' / 'none' / top_k(k) — retention decides what evidence is DESTROYED and has no default |
Pass a documented retention policy |
site_sweep_inputs_missing |
sweep_sites on the live_hook lane runs a REAL forward per candidate and needs model= and inputs= |
Pass both, or use engine='replay' |
site_sweep_duplicate_candidates |
Two candidates resolve to the same sites and units without a replicates=True declaration |
Deduplicate the plan, or declare the replicates |
site_sweep_site_key_unavailable |
A label-enumerated candidate's baseline op carries no structural site key (legacy capture); the engine executes in site-key coordinates (Build 0) so it cannot lower the candidate | Re-capture the baseline with a current TorchLens |
site_sweep_candidate_unresolved |
A sweep_sites candidate resolves to no site on the baseline; a zero-site candidate would run nothing and measure the baseline under its own name |
Check the spelling against baseline.ops (labels renumber between captures) or pass a selector that matches |
grid_axes_invalid |
sweep_grid axes= is not a non-empty mapping of axis name -> values, an axis has no values or is not a list / mapping, or a value name is empty, contains a comma, repeats within its axis or is the reserved baseline |
Declare axes={"name": [...]} or {"name": {"value name": value}} with unique comma-free names |
grid_axis_mixed |
A sweep_grid axis mixes sites (selectors, Selections, labels) with edits, or holds a value of neither kind |
Keep each axis sites-only or edits-only; wrap hook callables with the helper constructors |
grid_site_axis_missing |
sweep_grid axes hold no site axis |
Add one axis of selectors, Selections or labels, even with a single value |
grid_edit_axis_multiple |
More than one sweep_grid axis holds edits; one edit axis is allowed |
Keep one axis of edits |
grid_edit_conflict |
sweep_grid got both an edit axis and edit= |
Drop one of them |
grid_edit_missing |
sweep_grid got neither an edit axis nor edit=; the edit is the user's scientific choice and has no default |
Pass edit= or give one axis edit values |
grid_cell_uncombinable |
A sweep_grid cell's site values cannot be combined: a facet selector pairs only with exactly one module value (becoming facet.in_module(address)), and other values must support & |
Pair the facet with a module axis, or spell the site as one value |
grid_position_out_of_range |
A sweep_grid cell's tl.positions edit names an integer position beyond the extent its site recorded on the position axis; checked against recorded shapes before any forward |
Shrink the position axis or pick a wider site |
grid_too_large |
The product of the sweep_grid axis lengths exceeds max_cells= |
Lower an axis or raise max_cells |
grid_cell_unresolved |
Per-cell outcome, not a raise: a sweep_grid cell resolves to no site on the baseline, so it is a refused effect row (NaN in values, listed in SweepGrid.refused) while every other cell runs |
Check the cell's labels and selectors against baseline.ops |
grid_cell_multi_site |
Per-cell outcome, not a raise: a sweep_grid cell resolves to several sites (or an unprovable count) without a multi_site declaration, so it is a refused effect row while every other cell runs |
Pass multi_site=True or add the cell id to multi_site= |
grid_cell_unknown |
SweepGrid.coords(candidate_id) named no cell of this grid |
Use a cell id from grid.cells (the comma-joined value names) |
grid_coords_invalid |
SweepGrid.index / .candidate_id / .cell coordinates miss an axis, name an unknown axis or an unknown value name |
Pass every axis by keyword with a declared value name |
grid_axes_unavailable |
EffectsView.to_grid() on an operation that recorded no axes: the table was written by sweep_sites, not sweep_grid |
Run sweep_grid, or read the effect table directly through bundle.effects() |
grid_result_shape_mismatch |
EffectsView.to_grid() found effect rows and recorded axes that do not match one-to-one, or no baseline value; the artifact was not written by sweep_grid for these axes |
Rebuild the grid from an unedited sweep_grid artifact |
site_table_empty |
A zero-site find_sites() table was passed as an intervention address, or .first() was read from one: there is nothing to address, and an empty address must never silently no-op (leverage B3/NEW-4; experimental) |
Re-run find_sites(...) with a query that matches |
model_input_selector_not_live |
tl.model_input(...) was given as a live hook application site (Trace.do (including its set_only engine), clear_edits, a rerun's staged edit); model inputs are saved input placeholders, not hook sites, so the refusal names that condition instead of "matched 0 sites" (SelectorCapabilityError; experimental) |
Hook a downstream op (tl.func(...), tl.module(...)) or change the model input before capture |
site_selector_not_live |
tl.site(...) was given as a live hook application site; structural site keys do not exist mid-attach (SelectorCapabilityError; experimental) |
Resolve the site on the finished trace (trace[...], do) or pass the selector through trace(save=/intervene=) |
followed_by_selector_unsupported |
tl.followed_by(...) was evaluated outside capture-time save predicates; the lifecycle has no retroactive window (SelectorCapabilityError; experimental) |
Use it only in trace(save=...) / record(save=...) with lookback=N |
preceded_by_selector_unsupported |
tl.preceded_by(...) was evaluated outside capture-time save predicates (SelectorCapabilityError; experimental) |
Use it only in trace(save=...) / record(save=...) predicates |
facet_selector_unsupported |
A tl.facet(...) / tl.head(...) selector was given where facets do not resolve (find_sites, a composite selector other than a union of facet selectors given to do) (SelectorCapabilityError; experimental) |
Resolve facets through Trace.set, do (several at once as a union of facet selectors) or trace[selector] |
site_selector_no_match |
A post-capture selector given as an intervention or hook target matched no site on this trace (SiteResolutionError; experimental) |
Run find_sites(...) or trace[selector] to discover labels and widen or correct the selector |
site_selector_excess_fanout |
A selector matched more sites than max_fanout allows (AmbiguousSiteError; experimental) |
Pass a larger max_fanout explicitly or narrow the selector |
max_fanout_invalid |
max_fanout was None or below 1 (SiteResolutionError / AmbiguousSiteError; experimental) |
Pass an explicit integer of at least 1 |
bare_string_selector_strict |
A bare string selector was passed under strict=True; strings are not portable (SiteResolutionError; experimental) |
Use tl.label(...), tl.func(...) or another typed selector |
label_selector_not_live |
A live selector (intervene=, a sticky hook staged by do, a rerun's staged edit) named a finalized postprocess label (tl.label('relu_1_3'), tl.label('buffer_1:1')); live selectors run during capture before those labels exist, so it could never match (LiveModeLabelError; experimental) |
Select the site on the saved trace with tl.where(lambda p: p.layer_label == ...) through the replay engine, or aim the live hook with a capture-time selector such as tl.func(...) or tl.module(...) |
where_predicate_not_callable |
tl.where(...) carried a payload that is not a callable predicate (SiteResolutionError; experimental) |
Pass a callable taking the record context |
live_predicate_failed |
A tl.where predicate raised while a live capture evaluated it at an op; the user's exception is chained (SiteResolutionError; experimental) |
Make the predicate tolerate live contexts (no post-capture fields), or express the term structurally |
followed_by_composition_unsupported |
tl.followed_by(...) was evaluated standalone, negated, or OR-composed at capture time; it is only sugar for candidate & tl.followed_by(successor) (SelectorCompositionError; experimental) |
Write candidate & tl.followed_by(successor) |
facet_selector_invalid |
A facet target spec payload named neither a facet name nor a head index (SiteResolutionError; experimental) |
Re-save the spec from tl.facet(name) / tl.head(i) |
backward_pass_selector_invalid |
A backward_pass target spec payload is not an integer pass index (SiteResolutionError; experimental) |
Re-save the spec from tl.in_backward_pass(n) |
composite_selector_invalid |
An and / or target spec payload is not a sequence of nested selector specs (SiteResolutionError; experimental) |
Re-save the spec from the composed selector |
lookback_selector_inner_opaque |
A followed_by / preceded_by target spec carries an opaque audit payload (an inner predicate saved by repr), which cannot be rebuilt (SiteResolutionError; experimental) |
Rebuild the selector in code, or re-save with a structural inner such as tl.func(...) |
selector_kind_unsupported |
A target spec names a selector kind this TorchLens does not know (SiteResolutionError), or a selector kind has no evaluator for the requested lifecycle (SelectorCapabilityError); experimental |
Re-save the spec with this version, use a selector kind that lifecycle evaluates, or upgrade TorchLens |
live_hook_selector_unsupported |
A live hook target is neither a selector, a target spec, a label string nor a labelled record (SiteResolutionError; experimental) |
Pass a tl.* selector, a label string, or a record from the trace |
site_query_unsupported |
A post-capture site query (find_sites, trace[...], an intervention target) is neither a selector, a target spec, a string nor a find_sites() table (SiteResolutionError; experimental) |
Pass a tl.* selector, a substring, or a find_sites() result |
effects_selection_unavailable |
effects.selection() needs the sweep's session WHERE objects; a loaded artifact carries only the numeric table (Selections are session-only by design), or the view holds no convertible region |
Re-run the sweep in-session, or rebuild the region from the candidate ids |
effects_table_missing |
bundle.effects() found no stored effect table (or an unknown operation id) — the table is engine-written DATA, never recomputed |
Run sweep_sites first, or name a stored operation id |
head_ablation_module_unresolved |
The head-ablation sugar could not resolve the named module on the baseline trace (scoping is mandatory) | Name a captured module address |
head_ablation_equivalence_undeclared |
The module's attention geometry is GQA/MQA (one KV head serves several query heads) or underivable, so the v-facet lowering may not claim single-head semantics | Use a per-query-head recipe, or ablate the z/result facet with your own oracle |
head_ablation_heads_invalid |
The head set is empty or outside the module's head geometry | Pass indices inside range(n_heads) |
sweep_baseline_absent |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): a sweep bundle built with no pristine baseline member |
Pass include_baseline=True |
bundle_gate_ordering_topology |
A comparison-grade Bundle read (at(site).compare()/most_changed/compare) named operands joined by a directed path of ordering relations (successor_of/forked_from/escalates/fed_by/selected_by) — ordered members (e.g. successive conversation turns) are not comparison operands, regardless of relationship rank (A-GATE item 4) |
Compare peer members (e.g. alternative_of counterfactuals), or bundle the captures to compare without an ordering row between them |
bundle_gate_model_axis_unmet |
A gated Bundle read's operand pair derives a relationship below the operation's model-axis floor (node needs same_param_shapes; comparison reads need shared_graph), or the members contradict each other on operation order so the merged supergraph has no topological order true for every member |
Bundle captures whose models share the required structure (see Bundle.comparability), or use per-member reads such as Bundle.map |
bundle_gate_input_values_differ |
A comparison-grade Bundle read's operand pair captured different input VALUES (retained input payload digests disagree) AND their graphs do not line up (graph-shape hashes differ, for example data-dependent control flow took another branch), so sites cannot pair one to one; runs on different inputs whose graphs line up compare | Compare runs whose graphs line up, compare one shared site with Bundle.at(site), or use per-member reads such as Bundle.map |
bundle_gate_input_identity_unproven |
A comparison-grade Bundle read's operand pair has no value-level input evidence (inputs not saved, or a loaded artifact without input activations) AND their graphs do not line up (graph-shape hashes differ or are missing) — unproven input identity never passes on rank or a shape-level hash | Capture with input payloads retained (default save policy) or save with activations included; the persisted input_digest carrier lands with A-GATE/digest |
backend_payload_unsupported |
Backend payload has no supported codec (BackendPayloadUnsupportedError, dual ValueError + NotImplementedError lineage) |
Save metadata only or use another backend |
backend_runtime_compatibility |
Runtime cannot materialize serialized backend data | Install a compatible runtime or analyze only |
backend_unsupported |
Backend does not implement the requested capability (BackendUnsupportedError, dual ValueError + NotImplementedError lineage; the TF site-reachability subclass shares it) |
Omit it or use another backend |
buffer_visibility_invalid |
Unsupported show_buffers value |
Choose a documented visibility policy |
bundle_member_payload_missing |
Bundle member retained no tensor at this node | Query a node with stored tensors |
bundle_member_unknown |
Bundle member name is not in the bundle | Pass a known member name |
bundle_shape_mismatch |
Bundle members have incompatible shapes | Query members with matching shapes |
bundle_stack_incomplete |
Not every bundle member retained a tensor | Stack where every member has a tensor |
bundle_diff_layout_invalid |
Bundle diff layout is unsupported | Pass layout='paired' |
bundle_diff_members_invalid |
Bundle diff sides are missing or identical | Name two distinct members |
bundle_statistic_invalid |
Bundle statistic is unknown | Choose mean, std, var, or norm |
checkpoint_series_live_params |
Cross-member parameter value/difference/trajectory read (Bundle SuperParam, two or more members) with no immutable capture-time parameter evidence: parameter reads resolve through live model handles (or nothing after deserialization), so two members of a checkpoint series would report identical weights -- or degrade to NaN/empty -- never the per-member capture values (ParamEvidenceMissingError; keyed on the claim, never object identity; refuses BEFORE tensor lookup; the future R8(b) snapshot basis is the only pass) |
Snapshot parameters at capture, or bind each member to an immutable checkpoint; the ordering claim stays valid |
check_already_attached |
ChecksSession.attach() on a session that is already attached; one session owns one training loop's step axis (CheckLifecycleError) |
Detach first, or use one session per training loop |
check_boundary_nested |
A checks step boundary (with session.step():) opened inside an open boundary; attempts never nest (CheckLifecycleError) |
Close the open step() context before opening another |
check_bounds_invalid |
Malformed bounds for a checks-kit registration or audit: not a (low, high) pair, non-numeric sides, or low > high (CheckConfigError) |
Pass {'name': (low, high)}-style entries with None for an open side and low <= high |
check_fraction_invalid |
A checks-kit fraction knob (max_fraction, subnormal_fraction_threshold) outside [0.0, 1.0] (CheckConfigError) |
Pass the fraction between 0.0 and 1.0 |
check_no_accepted_steps |
WARNING (not a refusal): the death-spiral watchdog saw N backwards since the last accepted optimizer step exceeding the threshold — under a GradScaler this is the scale-collapse signature (every attempt skipped; retrospective methods stay silent forever) | Inspect the skip ledger (report().ledgers['scale']); check the loss for nonfinites and the scaler's init_scale |
check_optimizer_overlap |
A watched parameter is owned by more than one optimizer with no explicit ownership declaration; overlap is never silently resolved (CheckConfigError) |
Give each parameter exactly one optimizer, or run one session per optimizer |
check_optimizer_required |
An S-B/S-C-family check was registered on a session constructed without optimizer= (CheckConfigError) |
Pass optimizer= at construction, or register only the S-A tier |
check_target_invalid |
A checks-kit target is neither an nn.Module nor a name->tensor Mapping (CheckConfigError) |
Pass the module itself, or dict(model.state_dict()) / any name->tensor mapping |
check_vocab_invalid |
A closed-vocabulary checks-kit token (action=, evidence=, event kind=) is outside its declared vocabulary (CheckConfigError) |
Pass a documented vocabulary value (e.g. evidence='clone' exact, or 'digest' labeled opt-in) |
check_window_invalid |
A checks-kit M-of-N window, cadence (every=), or threshold pair is malformed (CheckConfigError) |
Pass window=(m, n) integers with 1 <= m <= n, every >= 1, positive thresholds with vanishing < exploding |
check_within_unknown_name |
A checks-kit within=/frozen declaration named a parameter absent from the watched set (CheckConfigError) |
Use exact qualified names from named_parameters() |
code_panel_callable_return_invalid |
Callable code panel returned a non-string at render time (ArgumentTypeError) |
Return the panel text as a string |
code_panel_model_collected |
Callable code panel needs the live model | Use a built-in code_panel mode |
code_panel_option_invalid |
Code panel mode literal is unknown (InvalidArgumentError) |
Pass a documented mode or a callable |
code_panel_side_invalid |
Code panel side is unknown | Pass side='right' or 'left' |
comparison_name_required |
Bundle comparison metric is a callable, which has no derivable stable storage name (InvalidArgumentError) |
Pass an explicit name= for callable metrics |
comparison_unknown |
No Bundle comparison was stored under the requested name (InvalidArgumentError; the message lists the stored names) |
Store the comparison first or query a stored name |
custom_callable_import_path_missing |
Custom function registry key lacks its import_path reference (InvalidArgumentError) |
Supply import_path='module:qualname' on the registry key entry |
custom_callable_module_denied |
Custom callable resolves from a dangerous or stdlib/builtin module; denied even under trust (UntrustedCallableError) |
Ship the recipe in a user module; dangerous modules never resolve |
custom_callable_module_not_allowlisted |
Custom callable's module is not in allowed_custom_callable_modules (UntrustedCallableError) |
Add the named module to the allowlist if trusted |
custom_callable_not_pure |
Bundle-supplied callable is not a pure forward/tensor op (UntrustedCallableError) |
Use pure forward/tensor ops in portable specs |
custom_callable_private_first_party |
Torchlens-owned callable is private or side-effecting; only vetted-inert public helpers auto-trust (UntrustedCallableError) |
Reference a public facet recipe/transform/intervention helper |
custom_callable_untrusted |
Foreign custom callable resolution was not trusted (UntrustedCallableError) |
Pass allowed_custom_callable_modules={<named module>} for a trusted spec |
capture_context_required |
Capture-only helper called outside trace() (also observers.log_value) |
Call it from the captured forward |
forward_raised |
The model's forward raised a non-TorchLens exception during a capture (the model's own code, a user hook, or a torch op it called; origin user_op, or unknown when no frame could be attributed). Every capture door raises TraceCaptureError chained from the original (exc.__cause__), with exc.partial_trace holding what was captured before the failure (experimental) |
Fix the model's own error (read exc.__cause__ and its traceback); inspect exc.partial_trace for the ops captured before it |
capture_internal_error |
The forward raised a non-TorchLens exception whose innermost attributable frame is inside TorchLens (TraceCaptureError, origin torchlens): most likely a TorchLens bug, never the model's code (experimental) |
Report it with the chained traceback (exc.__cause__); run the forward outside tl.trace to confirm the model itself is fine |
cleanup_during_active_capture |
Trace.cleanup() on the trace a live capture window is writing into |
Let the capture or backward projection finish first |
child_process_capture_unsupported |
Capture attempted from a non-deliberate child process | Capture from the owning process, or an initialized SPMD rank |
unwrap_during_active_capture |
unwrap_torch() called while a capture is running |
Finish or abort the capture before unwrapping |
pristine_ledger_poisoned |
The _decorated_to_orig unwrap ledger records a TorchLens wrapper as an original callable, so the pristine-torch restoration cannot be trusted |
Restart the process; if it recurs, a wrap-machinery defect is recording wrapped callables as originals — report it |
collapse_level_invalid |
Float collapse level is outside [0, 1] |
Choose an in-range level |
pattern_collapse_combination_unsupported |
fold_patterns= combined with automatic collapse; v1 supports the pattern-only view (collapse="none") and refuses the combination rather than double-counting chip members (collapse) |
Draw with collapse="none" for the pattern-only view, or drop fold_patterns |
pattern_fold_refusals |
WARNING code (TorchLensWarning): matched pattern instances refused on the honesty checks, counted and disclosed per pattern (collapse) |
Inspect the disclosed counts; adjust the pattern or accept the refusals |
pattern_name_invalid |
A pattern declaration used an empty name | Declare patterns as {'Name': 'atom > atom > ...'} |
pattern_no_match |
WARNING code (TorchLensWarning): a declared pattern matched zero sites (collapse) |
Check the pattern path against the trace's vocabulary |
pattern_rank_layout_unsupported |
fold_patterns= combined with layout="rank"; the rank backend cannot position segment-family chip nodes yet (the pre-existing __segment__ gap, owned by the typed-units item) |
Render with layout="dot" (or "auto") |
pattern_request_invalid |
fold_patterns= received an unsupported value type |
Pass None, 'idiomatic', a name-to-path mapping, or parsed PatternSpec records |
pattern_syntax_invalid |
A pattern path is empty, an atom is malformed, or an exact repetition is below 1 | Declare a linear path such as 'conv2d > batch_norm > relu' with optional atom{k} |
pattern_token_unknown |
WARNING code (TorchLensWarning): a pattern atom matched nothing in the trace; near-miss suggestions included (collapse) |
Use a suggested token or inspect the trace's op families |
collapse_mode_invalid |
Collapse mode is unsupported — PER-SURFACE DOMAINS: rendering collapse= accepts none/auto/max/float, the internal plan function accepts auto/max/float, the internal ranking function accepts only auto/max |
Choose a mode documented for that surface; the raised remedy names the exact set |
collapse_plan_unavailable |
Collapse optimizer declined the render context, or the drawing carries no plan: made with collapse='none', not a forward graph, or its trace has been released |
Read collapse_plan / collapse_schedule on a forward trace.draw(collapse=...) result while the trace is alive; use a supported render context and mode |
collapse_plan_cohorts_changed |
A persisted collapse plan was reapplied (strict, the default) on a capture whose structural cohorts changed — the guarded join refused or one-sided them, and reapplying anyway would silently fold different structure (leverage B13; experimental) | Re-export the plan on the new capture, or pass strict=False for the changed-set report |
collapse_plan_payload_invalid |
A tl_collapse_plan_v1 payload is malformed or foreign; torn plans never half-apply (leverage B13; experimental) |
Re-export with export_collapse_plan(trace) |
cone_origin_invalid |
cone_of_effect received a string (or other non-op) origin: iterating a string walks its characters and would silently return an empty cone (leverage B3; experimental) |
Resolve labels first — trace.layers[label].ops or trace.find_sites(label) |
container_leaf_not_saved |
Container leaf value was not retained | Re-run with save= covering the leaves |
container_not_reconstructable |
Container spec or backend support is absent | Capture with capture_container_structure=True |
container_selector_requires_registry |
Snapshot selector on a non-registry view | Call reconstruct() without site/role |
container_selector_unresolved |
Container selector matched zero or many records | Pass a more specific site=/role= |
container_spec_inadmissible |
Recorded output-container spec is corrupt, tampered, or names an inadmissible type (ContainerReconstructionError, ValueError lineage; default-deny security tripwire, also raised by public Op.multi_output_type) |
Re-save the artifact from a trusted capture |
container_value_source_invalid |
Container value source is unknown | Pass values='out' or 'transformed' |
context_field_invalid |
Persisted execution-context field fails its closed-vocabulary parse | Re-export the artifact; do not hand-edit descriptor context fields |
decoded_output_not_classification |
Decoded output is not a batch top-k table | Capture with classification output decoding |
decoded_output_unavailable |
Logits were not retained for re-decoding | Capture with retained logits or lower top_n |
derived_field_assignment_invalid |
Assignment to a derived compatibility field | Do not assign derived fields |
compiled_callable_unsupported |
Compiled plain callable has no module capture surface | Pass the original eager module |
compile_counts_unavailable |
tl.debug.count_compiles() found no Dynamo compile counters in this torch runtime (CompileCountsUnavailableError, RuntimeError lineage) |
Upgrade torch or skip the verification on this runtime |
determinism_runs_invalid |
tl.debug.check_determinism(runs=N) with N < 2 -- one run cannot support a repeatability claim (experimental) |
Pass runs=2 or more |
diagnostic_severity_invalid |
Diagnostic severity is outside the closed vocabulary | Choose a documented severity |
differential_status_invalid |
DiffReport.rows_with_status() got a status outside the closed added / removed / unresolved / excluded_machinery / unreachable / zero / changed vocabulary (leverage B15; experimental) |
Pass one of the closed row statuses |
differential_subject_is_reference |
diff(subject, reference) received the same capture on both sides — every row would be vacuously zero (leverage B15; experimental) |
Pass two different captures (a fork after do() is a different trace) |
digest_hash_invalid |
merkle_digest got a hash name outside the closed blake2b/sha256 vocabulary; the name is recorded in the manifest as a recomputation contract (experimental) |
Pass hash_name='blake2b' (default) or 'sha256' |
distributed_payload_witness_unsupported |
Payload witnesses are reserved | Use digest witnesses |
distributed_witness_invalid |
Distributed witness mode is unknown | Choose none or digest |
encoding_callable_error |
An encoding-channel user callable (color_by=fn) raised while resolving a node's value; the original exception is chained. UNSTABLE code (pre-ratification) |
Fix the callable; read Layer.ops for per-pass truth instead of per-pass attributes on rolled aggregates |
encoding_requires_dot_layout |
Explicit layout="rank" with an active encoding channel (color_by); v1 channels are dot-layout-only. UNSTABLE code (pre-ratification) |
Pass layout="dot" or layout="auto", or drop the channel |
encoding_source_invalid |
An encoding-channel source names no known record field or scalar builtin, or (on a rolled multi-pass node) a field with no declared rolled-aggregate semantics row. UNSTABLE code (pre-ratification) | Pass a Layer/Op field name, a scalar builtin, or a callable; unroll the graph for per-pass sources |
encoding_scale_invalid |
scale= is outside the closed size-channel vocabulary ("sqrt"/"linear"; log rejected by design). UNSTABLE code (pre-ratification) |
Pass scale="sqrt" (default) or scale="linear" |
escrow_budget_exceeded |
A deferred-selector escrow's temporary-disk spill crossed its DECLARED per-capture bound (leverage B9: the candidate-class escrow used to spill unboundedly; SaveBudgetExceededError with spilled_bytes/pending_bytes/budget_bytes on fields) |
The message names the components that forced the escrow and ends with the live spelling for them (fields["remedy"]). A tl.module(...) selector alone, joined by \| with other module paths, or intersected with any selector by & escrows only the ops that run inside a matching module pass and keeps only its outputs; when one pass alone crosses the bound, the remedy names save=tl.where(lambda ctx: ctx.address == path) (the module's own body, no escrow). Final-numbering selectors (op labels, positive ordinals, output spellings) and tl.module joined by \| with a non-module term, or negated, escrow every op's output; address them by module path, tl.func(name), a bare type-name string, or a save= predicate. torchlens._capture.preflight.address_preflight names the equivalent |
encoding_value_invalid |
An encoding-channel source produced a value the channel cannot encode (bool, non-scalar tensor, shape from a callable, or other non-numeric). UNSTABLE code (pre-ratification) | Encode a numeric source, or convert the value inside a callable |
execution_effect_invalid |
An engine tried to write an execution_effect disclosure outside the closed two-value vocabulary (values_replaced_after_execution / exits_substituted_interior_not_replayed); "skipped"/"deleted"/"removed" are unrepresentable by construction (experimental) |
Write values_replaced_after_execution (live/bound lanes) or exits_substituted_interior_not_replayed (replay) |
edge_intervention_engine_unsupported |
do() over an EDGE selection on the rerun/set_only engines; edge substitution ships on the replay engine only (experimental) |
Run the edge intervention on the replay engine |
edge_intervention_save_unsupported |
Save of a trace carrying tier-(ii) edge-substitution entries under a schema whose active policy would drop them (schema-regression tripwire; the tlspec v8 bump persists the carriers, so ordinary saves proceed; experimental) | Save the un-edited source trace, or restore the persisting carrier policy |
edge_provenance_unavailable |
trace.graph.edges / EDGE-kind resolution on a capture without edge provenance (replayable not armed; experimental) |
Re-capture with CaptureOptions(replayable=True) |
env_flag_invalid |
A TorchLens boolean environment variable is set to an unrecognized value | Use 1/true/yes/on or 0/false/no/off, or unset the variable |
factcore_grain_invalid |
FactCore counts were asked for a grain outside the closed menu (op / layer / site / module / call) (InvalidArgumentError, ValueError lineage; experimental) |
Pass one of the grain-menu tokens; the bare word "operations" has no grain |
factcore_identity_unknown |
An IdentityIndex join received a label or site key the identity spine does not carry — a silent empty join would fabricate absence (InvalidArgumentError, ValueError lineage; experimental) |
Use a label from identity.op_labels / identity.layer_labels or a key from identity.op_sites |
flop_convention_invalid |
An FMA convention outside {1, 2} was requested |
Pass fma=2 (stored convention, one MAC = 2 FLOPs) or fma=1 |
flop_convention_unavailable |
Explicit fma=1 request over ops with no derivable MAC split | Report under fma=2, or register a cost rule declaring the split (register_op_rule) |
flop_count_option_invalid |
A FLOP count got an unknown option, the removed count_fma_as_two= spelling, or a flop_convention outside 'fma2'/'fma1' |
Pass flop_convention='fma2' (was count_fma_as_two=True) or flop_convention='fma1' (was False) |
episode_declaration_invalid |
The episode= declaration is unusable or does not match the executed episode: the stepped module is not a proper submodule of the traced root; step_output_kind is outside tokens/digest/none or contradicts step_output_from; the declared source names no root-output slot (the refusal lists the available slots), was not retained, or resolves to a non-tensor; a tokens kind meets a float/complex source (declare digest/none); the source carries fewer positions along step_axis than steps ran (evidence is tail-aligned); the forced-token feed is malformed; or the declaration combines with chunking, cache=True, or a value-free save policy under an evidence-deriving kind (step_output_kind="none" admits value-free saves; the structure-only combination refuses with structure_only_episode_unsupported) |
Fix the declaration per the teaching message; wrap the loop in an nn.Module, declare its stepped submodule, and declare the step-output kind/source for structured or non-token roots |
episode_declared_crossing_stop |
EpisodeOptions(feed="closed") with a DECLARED crossing: capture stops BEFORE entering the declared crossing step — the crossing is declared, so no observation is needed; the partial product (rows 0..k-1 complete) rides exc.partial_trace |
Re-run without feed='closed' to capture across the declared crossing with a disclosed declared join grade |
episode_feed_break_exogenous |
A measured cross-step join is broken by UNDECLARED exogenous content (the measured step_join envelope carries the grade, break step, and exogenous position count): the trace is intact and every recorded op is real, but the episode is chain-shaped at that join, so episode-dependent claims across it refuse — step-series reads, whole-episode replay (run(), run(fast=True)), the blessing fold (derive_episode_status), and escalation. Ops, values, graph, audit, and per-segment reads are unaffected. Under EpisodeOptions(on_feed_break="refuse") (the arm (b)) the settlement write itself raises this code with the settled product on exc.partial_trace |
Read per-row facts (trace.episode.rows), declare the crossing (EpisodeOptions(crossings=(k,))), or declare feed='closed' to refuse at capture time; recover a settlement-refused product via exc.partial_trace |
episode_feed_closed_violation |
feed='closed' was declared and an UNDECLARED crossing was measured: the strict arm halts capture at the NEXT step entry — the first point where the break is observable (one-step detection latency; rows 0..k-1 complete, row k interrupted, later rows absent on exc.partial_trace) — or settles typed over the completed capture when the break is only measurable against the settlement evidence column |
Re-run without feed='closed' to capture across the break with a disclosed join |
episode_join_declared_crossing |
An episode-dependent claim (step-series read, whole-episode replay, the blessing fold, escalation) crosses a DECLARED crossing: the crossing is disclosed and the trace intact, but a declared crossing is still not one closed feed — the run is chain-shaped by declaration | Read per-row facts and per-segment values; the chain verbs are the named future surfaces for expressing the run as segments |
episode_join_unmeasured |
An episode-SERIES claim was made over unmeasured or unchecked joins: the ledger carries no step_join envelope (a pre-measurement artifact or a failed live measurement) or a join graded unchecked (reason named in the refusal), so the step series is not one attested feed. Per-row reads are unaffected; the narrow replay/fold gates deliberately keep their shipped behavior on unmeasured artifacts |
Re-capture with this TorchLens to measure the joins, or read per-row step_output facts |
episode_ledger_incoherent |
Episode ledger geometry violates the monotone prefix law, a coherence arm, the declared step count, or the value-mode (tokens/digest) presence rule — or the payload carries a foreign family grammar version (episode_ledger_version != 2, including the version-less pre-v2 grammar with tokens/cache_len rows): cross-grammar payloads quarantine typed and never normalize. On load the ledger quarantines and the outcome derivation degrades fail-closed. Settlement-time refusals carry the settled product on exc.partial_trace |
Re-capture the episode with this TorchLens; a hand-edited or foreign-grammar ledger never loads as claims; recover a settlement-refused product via exc.partial_trace |
episode_ledger_payload_in_structure_only |
A structure-only episode ledger carries token payloads | Remove the token payloads or drop the structure-only marker |
episode_ledger_without_declaration |
An episode ledger is attached to a capture that carries no episode declaration — illegal per the marker-combination table | Capture with episode=EpisodeOptions(...) instead of hand-attaching a ledger |
episode_pass_window_occurrence_axis |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): a cross-pass window (stable_across_passes / pass_variance) resolved on an EPISODE capture — pass indices are per-site occurrence counters, never episode steps, and the payload discloses both counts (episode_steps, site_passes) |
Window by per-site occurrence deliberately, mapping occurrences to steps through trace.annotations['episode']['rows']; an explicit step axis is a named future surface |
episode_state_unsnapshotable |
Declared episode-carried state has no snapshot/restore support inside the declared checkpoint scope; refused at declaration time, before execution | Declare only snapshotable state, or make the item deep-copyable |
episode_step_ceiling_exceeded |
The declared episode step count (num_steps or the forced_tokens length) exceeds the wrapped-tier cost ceiling (100 steps; the measured cost is superlinear — gpt2-124M CPU N=100 = 657 s / 5.4 GB peak RSS); refused at declaration time, before execution |
Declare fewer steps, or pass EpisodeOptions(acknowledge_step_cost=True) to accept the diagnostic-tier cost explicitly |
episode_coupling_unbound |
The episode ledger's persisted capture digest disagrees with the digest recomputed from the product it rides — the ledger does not describe this execution (a foreign or tampered ledger; the episode binding check) | Re-capture, or recover the original product the ledger belongs to |
episode_coupling_unmintable |
The episode ledger predates capture-digest minting (a pre-binding artifact), so the ledger-to-product binding cannot be attested | Re-capture with this TorchLens version to mint the binding |
episode_coupled_replay_underivable |
run() on a COUPLED episode product (episode= x intervene=): the ledger attests one perturbed execution, and no run provider re-arms the capture-time intervention, so no engine can derive a fresh ledger for the re-execution (the verdict's replay law: derive fresh or refuse) |
Re-capture with tl.trace(model, x, episode=..., intervene=...) for a fresh coupled product, or capture without intervene= for a replayable episode |
episode_step_selector_invalid |
at_step(...) was built with zero steps, a negative/bool/non-int step, or a persisted episode_step target spec carries a non-sequence payload (experimental) |
Pass the 0-based step indices to match, e.g. at_step(0, 2) |
episode_step_selector_without_episode |
A step-qualified selector (at_step) was evaluated against a capture or product with no episode declaration: there are no steps to qualify, and matching nothing silently would invert the fires-at-every-step wrongness the qualifier closes |
Declare the episode — tl.trace(model, x, episode=tl.options.EpisodeOptions(...)) — or drop the step qualifier |
episode_step_unstamped |
A post-hoc step-qualified query resolved against an episode product whose ops carry no Op.episode_step stamps (a pre-stamping artifact) |
Re-capture the episode (or re-save from a fresh capture) with a stamping TorchLens version |
record_episode_unsupported |
tl.record(...) or tl.recording.Recorder(...) received episode=; episode capture (the step ledger, at_step selectors, coupled replay) runs on the exhaustive door (RecordingConfigError) |
Use tl.trace(model, x, episode=..., save=...) with the same declaration |
error_constructor_args_conflict |
Diagnostic constructor got message args and fields | Pass a message or named fields, not both |
extraction_intervene_invalid |
extract_dataset(intervene=) got something other than a non-empty Recipe; the spec's rule identities are what the artifact records and resume compares (experimental) |
Build it with tl.when(selector, helper), e.g. tl.when(tl.module("fc1"), tl.zero_ablate()) |
extraction_intervened_selector_layers_unsupported |
intervene= was combined with selector-valued layers=; the selector plan freezes against a clean batch-zero capture (experimental) |
Name the sites with a list or {key: layer} mapping of layer lookups |
extraction_intervention_batch_dependent |
An intervened-extraction action does not declare is_batch_independent=True (an opaque callable cannot), so each stored row could depend on which stimuli shared its batch (experimental) |
Use a batch-independent helper, e.g. tl.zero_ablate() or tl.mean_ablate(source, dim=None) with a precomputed source |
extraction_intervention_no_fire |
An intervened extraction's spec fired at no site on a batch; an artifact whose rows were never edited would state a counterfactual that never happened (experimental) | Check the selector against trace.ops of one batch: it must match a site every batch executes |
extraction_intervention_site_drift |
A batch's intervention fired at other structural sites than batch zero froze; one artifact records one counterfactual (experimental) | Extract stimuli whose forward reaches the same sites, or split them into separate artifacts |
extraction_left_padding_unsupported |
An extraction batch's attention-mask pad geometry is not right-aligned and correct position_ids cannot be derived for this model (no declared position_ids forward parameter); absolute-position models read wrong activations under left padding (measured rel 25.6% BERT / 41.6% GPT-2; experimental) |
Right-pad the batch (padding_side="right"), extract with batch_size=1, or include correct position_ids in each batch |
extraction_engine_unsupported |
torchlens.neuro.plan_extraction requested a non-trace capture engine (experimental): fastlog records a strict subset of trace's sites, so an engine swap changes what sites='all' MEANS; it is gated on the definitional parity suite and engine='auto' is dead (brainpipe) |
Use engine='trace' |
extraction_manifest_invalid |
A dataset-extraction artifact's manifest.json is unparseable, carries the wrong schema, is still in_progress, is missing ledgered shard files, or lacks a requested output key (experimental) |
Finish the run with resume=True, request recorded output keys, or delete the directory and re-extract |
extraction_plan_model_gone |
ExtractionPlan.run() was called after the planning model was garbage-collected (the plan holds it weakly; experimental) |
Keep the model referenced through run(), or re-plan with a live model |
extraction_plan_over_budget |
The planned run's PREDICTED peak (two-probe resident fit, basis disclosed) exceeds the usable memory budget at the requested batch size; the planner refuses with arithmetic and never shrinks a batch silently (brainpipe; layer chunking is never offered as a floor remedy) | Reduce batch_size (the only lever that reduces the capture base), raise memory_budget, or reduce with a transform |
extraction_plan_signature_mismatch |
ExtractionPlan.run() received stimuli whose per-item shape/dtype drift from the probed input signature; a plan is valid only for its signature (sequence length alone shifted the measured peak 6.1x on gpt2; brainpipe) |
Re-plan with probe inputs matching the run stimuli |
extraction_probe_invalid |
plan_extraction probe inputs are not a tensor with a leading stimulus dimension, or batch_size/num_stimuli are non-positive (experimental) |
Pass one real probe batch (e.g. stimuli[:4]) and positive sizes |
export_target_not_callable |
tl.export.register_target() received a non-callable exporter (export door; experimental) |
Pass the exporter function itself |
export_target_tier_invalid |
Export-target registration declares a tier outside the closed present/bridge vocabulary (experimental) | Declare tier='present' or tier='bridge' |
extraction_ledger_invalid |
An artifact-v2 ledger.jsonl is a symlink or not a regular file, a row names a shard that is not a bare batch_NNNNN.pt/.safetensors file inside the artifact (an absolute path, .., a subdirectory or a symlink), or the ledger holds an unparseable MIDDLE line; later rows depend on the cumulative row ranges before it, so the trusted prefix ends typed (a torn FINAL line is crash debris — dropped, never trusted, never fatal; experimental) |
Delete the output directory and re-extract, or restore the ledger from a backup |
extraction_ledger_prefix_broken |
A LEDGERED shard file is missing or byte-size-mismatched; under the append-only v2 ledger a committed row can never be rewritten, so both resume and load refuse instead of silently truncating (experimental) | Restore the missing shard file from a backup, or delete the output directory and re-extract |
extraction_model_identity_invalid |
model_identity= is outside its closed vocabulary ("measured" / "none" / an assertion Mapping — "is_sampled" is not offered: a sampled fingerprint admits exact algebraic collisions), or asserted was requested without an assertion (experimental) |
Pass "measured" (default), "none", or the assertion mapping itself |
extraction_reader_buffer_shards_invalid |
shuffled_batches(buffer_shards=) needs a positive integer (mixing buffer; experimental) |
Pass buffer_shards >= 1 (1 shuffles within one shard at a time) |
extraction_resume_model_identity_mismatch |
The resuming run's MODEL IDENTITY differs from the artifact's record (different measured digest, different assertion, cross-level comparison, or an unavailable record) — continuing would silently mix the artifact's activations with a different model's, the T-MODELSWAP hazard a random-init resume used to complete with (experimental) |
Resume with the exact model state that produced the artifact, or extract into a fresh directory |
extraction_resume_opaque_transform |
Resuming an interrupted artifact would run forwards through an OPAQUE transform step; an opaque callable's identity is a disclosure, not a proof, so the continuation cannot be verified to produce the prefix's numbers (transforms memo decision 14; experimental) | Register the transform under a versioned name (torchlens.transforms.register_transform) and pass the registered spelling on both runs, or extract into a fresh directory |
extraction_resume_requires_output_dir |
extract_dataset(resume=True) without path=; only disk mode leaves a shard ledger to resume from (experimental) |
Pass path= or drop resume=True |
extraction_resume_signature_mismatch |
A resumed extraction's semantic run parameters differ from the artifact's recorded signature, compared FIELD BY FIELD against the known-fields list (layers, batch size, transform chain, stimulus descriptor, stimulus-id digest, mode/pad policies, integrity policy, ...); the refusal names the exact fields (experimental) | Re-run with the artifact's original configuration, or delete the output directory to start fresh |
extraction_resume_unmanifested_dir |
resume=True on a directory holding batch shards but no manifest; completed work cannot be verified (experimental) |
Delete the output directory (or use a fresh one) and re-run |
extraction_stimulus_ids_cardinality |
stimulus_ids disagrees with the stimulus count — a sized input validates upfront, an unsized iterable refuses before the first under-covered shard commit; a mis-lengthed id list would mislabel every later row (experimental) |
Pass exactly one identifier per stimulus, in order |
extraction_stimulus_ids_in_memory_unsupported |
extract_dataset(stimulus_ids=...) without path=: the in-memory result is a bare tensor mapping that can neither carry nor be affected by validated identifiers -- a false affordance (experimental) |
Pass path= to record stimulus identity in the manifest, or drop stimulus_ids= |
extraction_input_provenance_in_memory_unsupported |
extract_dataset(input_provenance=...) without path=: the in-memory result carries no manifest, so a provenance stamp could neither affect nor accompany the result -- a false affordance (tvscope B4; experimental) |
Pass path= to record input-preprocessing provenance in the manifest, or drop input_provenance= |
extraction_input_transform_missing_callable |
extract_dataset(input_transform=...) received a declaration-only resolution that carries no callable, so there is nothing to apply (tvscope B5; experimental) |
Resolve an authority that ships a transform (weights preset, processor, timm config), or apply your own transform and pass the resolution as input_provenance= instead |
extraction_input_transform_row_mismatch |
The input transform changed the stimulus-row count, so every downstream row would be mislabeled (tvscope B5) | Return exactly one transformed row per stimulus, in order |
feature_matrix_scalar_input |
The feature-matrix shaping op received a 0-dim tensor, which has no stimulus axis to shape into rows (tvscope B7) | Pass an activation tensor with a leading stimulus axis |
feature_rows_ids_mismatch |
Row-id cardinality disagrees with the stimulus-row count; proceeding would mislabel every row after the shorter of the two (tvscope B7) | Pass exactly one identifier per stimulus row, in row order |
feature_site_payload_unavailable |
The requested site holds no saved tensor payload (metadata-only trace) or is not an output key of the extraction artifact (tvscope B7) | Capture with save= selecting the site, or request an output key recorded in the artifact's manifest |
preprocessing_audit_mismatch |
The strict preprocessing audit found fields where the applied pipeline DISAGREES with the authority's declared configuration, named per field with both values (tvscope B3) | Apply the authority's own transform (resolution.input_transform) or correct the mismatched fields; rerun with strict=False for the full report without raising |
preprocessing_audit_unknown |
The strict preprocessing audit could not verify: fields undeclared on either side, an opaque transform, or a non-authoritative authority (the demoted ImageNet fallback and the declares-nothing families can never anchor verified) (tvscope B3) |
Supply a declared authority AND a declared applied side; rerun with strict=False to proceed on the honest unknown |
preprocessing_authority_unrecognized |
The preprocessing authority object matched no registered adapter (torchvision Weights preset, HF image processor, timm data config, Compose pipeline, declaration mapping) (tvscope B2) | Pass your loader's own preprocessing object or an explicit declaration mapping; register_authority_adapter() extends the recognized kinds |
preprocessing_diagnostic_unknown_check |
An unknown diagnostic check name was requested; the check vocabulary is closed and the confinement arm is opt-in-only (tvscope B3) | Pick from the documented check set (nonfinite, dtype_regime, layout, confinement) |
image_path_missing |
A tl.trace input names an image file (image suffix, no whitespace) that does not exist, and the model has no text tokenizer that could read the string as text (InvalidArgumentError) |
Pass the path of an existing image file, or an already-loaded image |
image_path_unreadable |
A tl.trace input names an existing image file that could not be opened as an image, a Trace.annotate(image=...) path does not name an image file Pillow can open, or Pillow is not installed (InvalidArgumentError) |
Check the file is a readable image, install Pillow, or pass an already-loaded image |
preprocessing_unresolved |
A PIL image reached capture but no preprocessing authority resolved from the model (no torchvision weights handle, no cached torchvision preset checkpoint equal to the loaded state, no timm data config or HF image processor); TorchLens no longer applies the ImageNet default silently (experimental). Also raised when a modality-key dict ({"text": ..., "images": ...}) reaches a Hugging Face model whose AutoProcessor does not load from the cache or the Hub (offline, no processor config): the raw dict is not a valid model input and never reaches the forward as input_ids |
Record the weights the model was built with (torchlens.preprocessing.attach_authority(model, weights); a torchvision model is recognised on its own only when its state equals exactly one preset checkpoint already in the torch hub cache), pass your loader's own transform (CaptureOptions(input_transform=weights.transforms())), opt in to the ImageNet default with CaptureOptions(input_transform=torchlens.preprocessing.imagenet_default()), or pass a preprocessed tensor. For the modality dict, run once with network access so the processor files join the cache, attach the processor (model.processor = AutoProcessor.from_pretrained(name)), or pass the processor's output yourself as input_kwargs |
preprocessing_attach_opaque |
torchlens.preprocessing.attach_authority got an object that resolves to an opaque callable declaring no preprocessing, so attaching it would record nothing (InvalidArgumentError; experimental) |
Attach the loader's own preprocessing object (weights preset, processor, data config, preprocess Compose) or a declaration mapping |
preprocessing_card_unresolved |
torchlens.preprocessing.check_card had no card to compare against: no authority= and no model (given, or live on the trace) (InvalidArgumentError; experimental) |
Pass model= or authority= |
preprocessing_card_mismatch |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): torchlens.preprocessing.check_card, called on request, found recorded preprocessing fields that disagree with the model's card (TorchLensWarning; nothing runs the check automatically; experimental) |
Apply the card's own transform, or read the returned report's mismatched fields |
site_selector_ambiguous |
A site spelling matched several inventoried sites (tvscope B6) | Pick one of the WORKING selectors listed in the remedy/fields["candidates"] |
site_selector_unknown |
A site spelling matched no inventoried site (tvscope B6) | Copy a selector from the inventory rows; the nearest working spellings are disclosed in fields["candidates"] |
extraction_stimulus_ids_sidecar_invalid |
The write-once ordered stimulus_ids.json sidecar is unreadable or already records a DIFFERENT id list; relabeling is a separate audited verb, never a resume side effect (experimental) |
Resume with the artifact's original stimulus_ids, or extract into a fresh directory |
extraction_as_captured_unavailable |
ragged="as_captured" (byte-exact batch-padded reproduction) is reserved and not yet available; the enum admits the value so adding the mode later is a value change, never a signature break (experimental) |
Use ragged="trim" (true per-stimulus extents) or pool= |
extraction_checksums_invalid |
checksums= is outside the closed fast/crypto/none vocabulary ('fast' = final-file CRC-32 + on-device value reduction; 'none' is a recorded opt-out that verification refuses; experimental) |
Pass "fast" (default), "crypto", or "none" |
extraction_collate_ambiguous |
A user collate= returned a bare tuple/list — ambiguous between positional args and one sequence-valued input (experimental) |
Return a BatchEnvelope, a Mapping (kwargs), or a single Tensor |
extraction_collate_invalid |
The collate= value is not callable, or its result carries no derivable positive row count — the row-truth every stored shard is validated against (experimental) |
Return a BatchEnvelope with the batch's true row_count, or a batched Mapping/Tensor |
extraction_disk_only_option |
A disk-only extraction option (shard_format=, non-default checksums=, pipeline_id=, non-default ragged=) was passed without path= — it could neither affect nor accompany the in-memory result, a false affordance (experimental) |
Pass path= (disk mode) or drop the options |
extraction_dtype_invalid |
dtype= is neither a torch.dtype nor an accepted name string (experimental) |
Pass a torch.dtype (e.g. torch.float16) or its name string |
extraction_dtype_unsupported |
The requested save-dtype cast kernel failed on the capture device, or the shard codec cannot store the target dtype (experimental) | Choose a supported save dtype, or shard_format="pt" |
extraction_eager_budget_exceeded |
An eager materialization's EXACT byte need (computed from ledger facts before any allocation) exceeds the budget (experimental) | Read lazily via open_extraction(...), request fewer keys, or override explicitly with max_bytes= |
extraction_export_dependency_missing |
The hdf5/mat exporters need their optional dependency, which is not installed (it ships behind the named extra, never on the default path; experimental) | pip install "torchlens[extraction-export]" |
extraction_export_destination_exists |
The export destination already exists; the exporter publishes atomically and never overwrites (experimental) | Point dest= at a fresh path, or delete the old export first |
extraction_export_dtype_unsupported |
A bf16/fp8 member cannot be represented by NumPy and widen_unsupported=False refused the disclosed fp32 widening (experimental) |
Allow the widening (default), or read the native artifact via open_extraction |
extraction_export_format_invalid |
format= is outside the closed npy/hdf5/mat export vocabulary (experimental) |
Pass "npy", "hdf5", or "mat" |
extraction_export_mat_v5_limit |
A key needs more bytes than the MATLAB v5 per-variable limit; an arbitrary HDF5 file is never mislabeled MAT v7.3 (experimental) | Export format="hdf5" and read it in MATLAB with h5read |
extraction_export_space_insufficient |
The destination filesystem lacks the export's exact byte need; NSD-scale exports transiently need source AND destination on disk (the transactional replace verb is deferred; the exporter never deletes its source; experimental) | Free destination space, or export a key subset (keys=) |
extraction_output_key_invalid |
A user output key is empty, non-string, over-length, or path-capable (/, \\, .., NUL) — keys become manifest entries and exporter filenames, validated at CALL time before any forward (experimental) |
Rename the key: non-empty string, bounded, no path separators |
extraction_pad_token_missing |
Batched text tokenization needs a pad token and the tokenizer has none configured (GPT-2 class); EOS-as-pad is an explicit, disclosed opt-in recorded as pad_token_source (experimental) |
Opt in with hf_collate(tokenizer, pad_token="eos"), or set tokenizer.pad_token |
extraction_pool_axes_ambiguous |
A pool preset cannot prove its axes on this site's geometry (spatial_* needs 4D maps, token_*/cls/last_token need 3D sequences); guessing would silently pool the wrong dimension (experimental) | Pick the preset matching the site's geometry, or pool per key |
extraction_pool_dtype_unsupported |
Pooling cannot run in the captured fp8 dtype (reduction kernels unsupported); pool runs in captured dtype by contract (experimental) | Capture wider and store fp8 via dtype= after pooling |
extraction_pool_invalid |
pool= is outside the closed preset vocabulary or carries unknown spec fields (experimental) |
Pass one of the documented presets or a per-key mapping of them |
extraction_pool_mask_required |
A mask-aware pool preset (token_*/last_token) has no attention mask, or the mask cannot be proven to describe the site's token axis; unmasked pad pooling was measured 20.66% wrong (experimental) | Collate with a mask (the HF helper supplies one), or record the explicit {"unmasked": true} override |
extraction_pure_module_invalid |
register_pure_module() got a dotted or unimportable name; purity is asserted per top-level installed namespace (experimental) |
Pass one top-level installed module name |
extraction_ragged_geometry_mismatch |
A tensor's token axis cannot carry the batch mask geometry, or to_padded(max_len=) is shorter than a stored row (truncation would silently drop values; experimental) |
Trim token-axis sites only; raise max_len or omit it |
extraction_ragged_invalid |
ragged= is outside the closed refuse/trim/as_captured vocabulary — an enum, not a bool (experimental) |
Pass "refuse" (default), "trim", or "as_captured" |
extraction_ragged_mask_noncontiguous |
A mask row's valid positions are not one contiguous span, so (start, extent) slicing would mis-read interior gaps; the full boolean mask is the only honest carrier (experimental) |
Fix the collator's mask, or pool the site |
extraction_ragged_refused |
A key changed per-stimulus shape across batches under ragged="refuse" (the default); refused BEFORE the offending shard commits — expect the preserved prefix to be a single shard on real text (experimental) |
Pool the site, collate to a fixed length, or opt into ragged="trim" |
extraction_reader_batch_size_invalid |
ExtractionReader.shuffled_batches() needs a positive batch size (experimental) |
Pass batch_size >= 1 |
extraction_reader_id_ambiguous |
A stimulus id names several rows (duplicates are legal in artifacts), so the singular lookup refuses (experimental) | Use rows_for(id) for every row index |
extraction_reader_id_unknown |
The requested stimulus id is not in the artifact's id sidecar (experimental) | Look up a recorded id (reader.stimulus_ids() lists them) |
extraction_reader_ids_unavailable |
The artifact records no stimulus-id sidecar, so rows cannot be addressed by identifier (experimental) | Extract with stimulus_ids=, or address rows by index |
extraction_reader_key_unknown |
The requested output key is not recorded in the artifact's manifest layers block, is stored in the other layout (dense vs trimmed), or is internally inconsistent (experimental) | Request a recorded key; read trimmed keys via row()/to_padded() |
extraction_reader_not_monitoring |
refresh() monitors a still-writing artifact and this reader was opened for a completed one (experimental) |
Open with open_extraction(dir, in_progress=True) to monitor |
extraction_reader_ragged_matrix_unsupported |
A trimmed key has no rectangular feature matrix (true per-stimulus extents vary; experimental) | Densify explicitly with reader.to_padded(key), or pool at extraction time |
extraction_reader_row_out_of_range |
A requested row or shard index is outside the artifact's trusted range (experimental) | Request rows in [0, num_stimuli) / shards in [0, n_shards) |
extraction_reader_verify_invalid |
verify= is outside the closed structural/first_access vocabulary; full verification is the explicit verify_all() call, never a per-read default (experimental) |
Pass verify="structural" or verify="first_access" |
extraction_relabel_invalid |
relabel_extraction targets COMPLETE artifacts with exactly one identifier per stimulus row (experimental) |
Finish the run first, or pass one id per row in order |
extraction_resume_callable_mismatch |
A callable slot classifies COMPLETE on both sides but the digests differ — its observable behavior changed since the prefix was written; the deliberate-refactor case needs the artifact's RECORDED pipeline_id= (experimental) |
Resume with the original callable, extract fresh, or attest with the recorded pipeline_id= |
extraction_resume_input_mismatch |
A replayed shard collates to a DIFFERENT input than the one its activations were extracted from (per-shard input_digest, recomputed during the zero-forward skip replay); the stimuli, their order, or the collation changed (experimental) |
Re-run with the original stimuli in order (deterministic collate), or extract fresh |
extraction_resume_pipeline_id_invalid |
pipeline_id= was supplied at resume time but the prefix recorded none — a newly invented ID cannot retroactively attest old callable semantics (strict continuity; experimental) |
Start a fresh artifact, or set pipeline_id= from the FIRST run |
extraction_row_count_mismatch |
A stored payload's row count disagrees with the INPUT batch's row truth after pooling/postprocessing; the shard is refused BEFORE its commit (row i of every shard is stimulus i; experimental) | Keep transforms row-preserving over the stimulus axis, or fix the collate row_count |
extraction_selector_excess_fanout |
A layers= selector matched more sites than the ceiling; every site becomes a stored, exported, manifest-described member, so an under-constrained selector refuses (experimental) |
Narrow the selector (compose with tl.in_module or type filters) |
extraction_selector_mixed_unsupported |
A layers= mapping mixes selector values and string lookups; one request resolves through one door so the frozen plan stays attestable (experimental) |
Split into one selector-valued and one string-valued call |
extraction_selector_no_sites |
A layers= selector matched ZERO saved sites on batch zero; an empty plan would complete an artifact with no data (experimental) |
Broaden the selector, or name layers by label |
extraction_selector_partial_units |
layers= received an element-level Selection; extraction stores WHOLE sites, so partial-unit selections cannot become stored keys (experimental) |
Pass the site's selector or label, then slice downstream with transform= or at read |
extraction_selector_plan_violated |
A batch resolved a DIFFERENT site plan than the frozen batch-zero plan (missing, extra, or reordered sites — the exact diff is named); rows written under a drifting plan would silently mix sites (experimental) | Make control flow batch-invariant for the selected sites, or extract varying sites separately |
extraction_selector_transform_mapping_unsupported |
Selector-valued layers= cannot take a per-site transform Mapping: the plan's output keys (including namespaced children) are unknowable before batch zero freezes them (experimental) |
Pass one global transform chain, or name sites with a string-valued mapping |
extraction_shard_format_invalid |
shard_format= is outside the closed safetensors/pt vocabulary, or .pt shards would be written or read on a torch whose torch.load(weights_only=True) a crafted file can bypass (CVE-2025-32434, torch 2.5.1 and older; such a shard is never unpickled) (experimental) |
Pass "safetensors" (default) or "pt"; for .pt on torch 2.5.1 or older, upgrade torch to 2.6+ or re-extract with shard_format="safetensors" |
extraction_shard_integrity_mismatch |
A shard fails its ledgered CRC-32 (bytes changed after commit) or its value reduction (values corrupted before the write); the trusted prefix ends here — checksum level 'fast' detects accidental corruption only (experimental) | Restore the shard from a backup, or re-extract |
extraction_stimulus_ids_invalid |
A stimulus identifier is empty or not a string; identifiers are non-empty strings, duplicates legal and recorded (experimental) | Pass one non-empty string per stimulus |
extraction_store_input_ids_absent |
store_input_ids=True, but the batch carries no token ids (no input_ids keyword and no sole 2-D integer positional argument) (experimental) |
Collate text batches with input_ids (hf_collate does), or drop store_input_ids= |
extraction_store_input_ids_invalid |
store_input_ids= takes True or False (experimental) |
Pass store_input_ids=True to store token ids, or omit it |
extraction_store_input_ids_key_collision |
store_input_ids=True stores ids under the output key input_ids, which an activation key already uses (experimental) |
Rename that layer key in a {key: layer} mapping |
extraction_token_rows_misaligned |
Two requested keys disagree on a stimulus's token count, so their token rows cannot be aligned (token store; experimental) | Read token rows for keys that share one token axis |
extraction_token_rows_unsupported_key |
A key has no honest token-row reading: no token axis, no recorded attention mask, or stored dense at a padded width (token store; experimental) | Extract token-axis sites with ragged="trim" (true extents), or request only token-axis keys |
extraction_tokenizer_unresolvable |
Text stimuli need a tokenizer and none resolved through the three doors (caller-supplied, attached model.tokenizer/to_tokens, hub lookup from the model config; experimental) |
Pass collate=hf_collate(tokenizer=...), or attach model.tokenizer |
facade_dependency_missing |
A real lazy-facade name's declared optional dependency is not installed, or its resolution import failed (MissingDependencyError, AttributeError lineage so hasattr answers False; the missing package and install command ride the message and exc.fields["dependency"]/exc.fields["install"] — CPython's instance-layout conflict forbids dual ImportError lineage; experimental) |
Run the install command named in the message (exc.fields["install"]) |
facade_redirect |
A lazy-facade attribute access hit a redirect row, or a removed public class member was looked up (Trace.replay, Bundle.rerun, VisualizationOptions.mode, ...), or a submodule made private was read as an attribute of its parent (the old types module of tl.intervention): the name is not active here and the message names the canonical spelling (FacadeTeachingError, AttributeError lineage; experimental). A from <module> import <removed name> statement shows a plain ImportError instead: CPython replaces the attribute error, so only attribute access carries the redirect; import of a private submodule's old path is a plain ModuleNotFoundError |
Use the canonical spelling named in the message |
facade_refusal |
A lazy-facade attribute access hit a refusal row: the name is deliberately not provided and the message names the owning tool or reason (FacadeTeachingError, AttributeError lineage; experimental) |
Follow the pointer in the message |
fold_repeats_invalid |
Repeat-fold policy is invalid | Choose None, True, or False |
followed_by_unsupported |
tl.followed_by(...) predicate shape or retroactive capture is unsupported on this surface (PredicateError, RuntimeError lineage) |
Compose candidate & tl.followed_by(successor) and capture with tl.trace(save=...) |
frozen_param_changed |
A tensor declared frozen moved between accepted optimizer steps; raise-class by default with exact clone evidence showing the offending delta and every alias of the moved tensor (CheckViolationError; demotable to warn/collect per registration) |
Remove the tensor from the optimizer / set requires_grad=False, or drop the frozen declaration if the movement is intended |
fsdp_capture_unsupported |
record() received an FSDP-wrapped model |
Record the unsharded module |
import_path_invalid |
Custom-callable import reference is malformed | Use the module:qualname form |
intervening_cluster_invalid |
Intervening-cluster policy is unknown | Choose upstream, outside, downstream, or own |
injection_logged_runnable_unsupported |
A RUNNABLE save of a trace carrying logged injected ops (log_injections=True): the sparse core is the model's taken-path DAG and cannot carry injected computation, so the artifact would silently drop it (experimental). Analysis-level saves persist the injected family |
Save at the default analysis level, or re-capture without log_injections for a runnable artifact |
injection_logged_stream_unsupported |
Finalizing a streamed storage=tl.to_disk(...) bundle on a trace carrying logged injected ops: the streamed writer stages its own bundle and never passes the analysis save door that appends the injected family (experimental) |
Capture without streamed storage and save the finished trace with trace.save(), or re-capture without log_injections |
injection_persist_unanchored |
Saving a logged trace whose injected-op record has no resolved host site key: the persisted identity anchors on the host's structural position (the injection_provenance slot) and cannot be written without one |
Re-capture on a backend/path that mints site keys, or re-capture without log_injections |
injection_persist_state_invalid |
Internal defensive guard: the scrub produced a portable state without a layer_list to carry injected-op rows -- a TorchLens scrub defect, not reachable from lawful user input |
Report the bug with the capture recipe; re-capture without log_injections to save meanwhile |
injection_persist_arg_unencodable |
Internal defensive guard: an injected-op replay-arg snapshot holds a value outside the closed encodable grammar, which the fire-time snapshotter never admits -- reachable only by mutating session-private injection records in-process | Do not hand-edit trace._tl_injection_state; re-capture to rebuild honest records |
intervention_tensor_unsupported |
Intervention save tensor fails the codec | Use dense, codec-supported tensors |
intervention_spec_not_portable |
Trace.save(level="portable") or save_intervention(level="portable") would write a recipe that cannot rebuild without user code: a rule holds a user callable (saved only as a placeholder) or a value the format cannot carry, or a capture predicate lacks a built-in selector (OpaqueCallableError or ArtifactError) |
Save at level="audit" for an audit-only record, or stage the rule with built-in edits |
facet_write_not_reproducible |
Loading a trace whose recipe holds a facet write (a tl.head(i, facet).in_module(m) selector plus a built-in edit): the stored selector does not re-resolve on the loaded trace to the same home op, facet and write mask (the mask's sha256), or the stored mask does not match its digest (ArtifactError) |
Re-attach the facet intervention on a live trace and save again; do not hand-edit the recipe |
layers_not_logged |
Rendering requires a fully-logged trace | Capture with full layer logging |
lazy_uninitialized |
Zero-input shape inference on a model carrying un-materialized lazy modules (a lazy module accepts any width, so probing has no error signal). Capture entry never refuses on pending lazy state: executed lazy modules (LazyLinear, LazyConv2d, LazyBatchNorm* running stats included) materialize during the ONE captured forward -- lazy pre-hook plumbing passes through the wrapper unlogged and materialized buffers register at the module-entry gate -- while never-run ones stay at zero geometry in the inventory |
Run one real forward pass to materialize the lazy modules, then retry shape inference |
history_size_invalid |
Recorder history size is out of range | Pass an integer in [0, 1024] |
grad_basis_invalid |
grad_health(basis=...) received an unknown classification basis (InvalidArgumentError) |
Pass basis='total_norm' (the default) or basis='rms' |
grad_magnitude_flagged |
FINDING (checks kit): a pre-clip S-A parameter-gradient norm crossed the registration's vanishing/exploding threshold; carries stage + scale_provenance (unknown provenance yields unknown verdicts, never a silent pass) |
Thresholds are per-registration pending the calibration matrix; follow up on the repaired grad_health module/frontier columns |
grad_scale_conflict |
grad_health received both grad_scale= and grad_scales= (KeywordConflictError) |
Pass one scale spelling: a single factor, or a per-backward mapping |
gradient_not_saved |
Requested gradient payload was not retained | Capture with gradient saving enabled |
graph_breaks_normalization_failed |
tl.debug.graph_breaks() got a Dynamo explain result of unrecognized shape (GraphBreaksNormalizationError, RuntimeError lineage) |
Report the shape to TorchLens or pin a recognized torch version |
graph_breaks_unavailable |
tl.debug.graph_breaks() found no torch._dynamo.explain in this torch runtime (GraphBreaksUnavailableError, RuntimeError lineage) |
Upgrade torch or skip the correlation on this runtime |
graphviz_binary_unavailable |
The Graphviz executable is not on PATH, so no render subprocess can start; or a rank-layout render finds no neato layout plugin in the installed Graphviz (GraphvizUnavailableError, RuntimeError lineage) |
Install the Graphviz system package (apt install graphviz / brew install graphviz); for the neato plugin on Debian forky and Ubuntu 26.04 or later, apt install libgvplugin-neato-layout8, or render with layout='dot' |
graphviz_render_failed |
Graphviz did not produce a usable rendered artifact (GraphvizRenderError, RuntimeError lineage) |
Lower dpi, render direct SVG, or cap the graph size |
gradient_pass_ambiguous |
Gradient query spans multiple backward passes | Pick one pass or record positionally |
grad_scale_invalid |
gradient_flow_audit(grad_scale=...) got a non-positive or non-finite loss scale (InvalidArgumentError) |
Pass scaler.get_scale() from the GradScaler the captured backward ran under, or omit grad_scale |
grad_fn_walk_no_graph |
tl.debug.walk_grad_fn/sketch_grad_fn got a tensor with no autograd graph (detached, a leaf, or computed under no_grad) (GradFnWalkError) |
Recompute the value with autograd enabled and pass a tensor whose .grad_fn is not None |
grad_fn_fire_timing_unavailable |
trace.autograd.grad_fn_fire_timings read on a trace without its runtime capture event stream (loaded artifact or cleaned trace); the event-stream accessor is live-trace-only (experimental) |
Read on the live capturing trace; loaded artifacts carry the persisted per-fire GradFnCall timing fields (tlspec v8, discriminated by Trace.grad_fn_timing_provenance) |
grouping_invalid |
grouping= value is outside the closed vocabulary |
Choose a documented grouping policy value |
grouping_policy_unavailable |
grouping= value is legal vocabulary but not entry-legal for this capture kind/wave (experimental) |
Use the default grouping='structural' |
halt_predicate_type_invalid |
tl.trace or tl.record halt is not callable (ArgumentTypeError, TypeError lineage on both entry points) |
Pass a predicate or None |
hash_content_type_unsupported |
tl.fingerprint.content value cannot be deterministically encoded (ArgumentTypeError, TypeError lineage) |
Pass tensors, arrays, builtin scalars/containers, or __dict__-inspectable objects |
hash_expected_type_invalid |
tl.fingerprint.assert_unchanged pin is neither a string nor None (ArgumentTypeError, TypeError lineage) |
Pass the pinned hash string, or None to bootstrap a pin |
inference_only_conflict |
inference_only=True combined with backward-related capture flags that need the discarded autograd graph (TrainingModeConfigError, ValueError lineage) |
Drop inference_only or drop the backward flag |
input_namedtuple_schema_not_total |
Model-input tuple subclass declares a namedtuple _fields schema that does not account for the physical tuple — malformed non-tuple-of-str _fields, or declared arity differing from physical arity (InvalidArgumentError) |
Fix the _fields declaration (one str per positional element) or pass a plain tuple/list |
input_tree_cycle |
Model-input tree contains a self-referential container (InvalidArgumentError) |
Remove the container reference cycle from the model input |
input_tree_depth_exceeded |
Model-input tree nesting exceeds the input-boundary depth ceiling (InvalidArgumentError) |
Flatten the nested input containers before tracing |
input_tree_stack_exhausted |
Walking the model-input tree exhausted the Python stack budget before the depth ceiling — capture was entered with most of the interpreter stack already consumed (InvalidArgumentError) |
Enter capture from a shallower call stack or raise sys.setrecursionlimit() |
input_kwargs_type_invalid |
tl.trace input_kwargs is not a Mapping — usually multiple positional inputs passed as separate arguments (ArgumentTypeError, TypeError lineage) |
Pass keyword args as a dict, or bundle positional inputs into one tuple |
input_rung_conflict |
A real input and input_shape= were both supplied; the input ladder's rungs are exclusive by law (ArgumentConflictError) |
Pass the real input alone, or drop it and keep input_shape= |
input_rung_requires_module_root |
input_shape=/inferred-input capture with a non-nn.Module root: declared and inferred rungs synthesize inputs from a module's geometry, which a bound-method root does not expose |
Pass a real input (the gold rung), e.g. tl.trace(model.generate, input_ids) |
input_size_invalid |
input_shape= grammar violation: empty, zero/negative/symbolic/bool dimension, or not a shape tuple / sequence of shapes / keyword-to-shape mapping (InvalidArgumentError) |
Use one flat positive-int tuple, a sequence of shape tuples, or a mapping of forward keyword names to shapes; torchlens.types.InputSpec pins dtype/value recipes |
input_size_unknown_binding |
input_shape= mapping binds a keyword the model's forward does not accept (InvalidArgumentError) |
Bind one of the forward's known keyword names (listed in the refusal) |
input_dtype_ambiguous |
No static model fact settles a dtype/value recipe for an input_shape= slot; TorchLens never discovers dtypes by running failed forwards (InvalidArgumentError) |
Pass torchlens.types.InputSpec(shape, dtype=..., low=..., high=...) for the slot, or a real input |
input_inference_failed |
The zero-argument rung could not infer a runnable input; the bounded probe diary rides exc.fields["attempts"] (ShapeInferenceError) |
Pass the real forward call; or input_shape= (mapping form for multi-input models); or run torchlens.debug.guess_input_shape with hints — for HF models a real prompt string is the better answer |
input_ladder_backend_unsupported |
input_shape=/zero-argument resolution requested with an explicit non-torch backend (InvalidArgumentError) |
Pass a real input for non-torch backends |
node_overlay_partial_match |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): a node_overlay mapping matched only some of its requested keys; painted nodes reflect the realized rows only |
Key the overlay table by the drawn trace's layer labels |
node_overlay_zero_match |
A node_overlay mapping matched ZERO of this trace's realizable node labels: nothing would be painted, and the door used to render a blank picture and report success (leverage B8; experimental) |
Key the overlay table by this trace's layer labels (the refusal lists examples) |
nongold_semantics_unavailable |
A derived-semantics claim (decoded labels/top-k, value-stat conclusions, value-driven render channels) was requested on a trace whose input values were synthesized (CaptureNotActiveError) |
Re-capture with a real input (or an HF prompt string) and make the claim on that trace |
nongold_raw_value_read |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): first raw value read on a trace whose input values were synthesized; fires once per trace object |
Re-capture with a real input for value-level claims, or filter the warning by its code to acknowledge |
render_engine_unavailable |
Graphviz (package or system binaries) missing or failed while rendering a detached render result (CaptureNotActiveError) |
Install Graphviz (pip install graphviz, apt install graphviz) or choose a supported format |
intervention_replacement_invalid |
Intervention replacement payload has the wrong shape/dtype/device (or is None/a non-tensor) at the matched site; the ONE payload gate for every edit door incl. region exit replacements on do(region, edit) (HookValueError) |
Fix the replacement tensor passed to the intervene= clause / region edit |
layers_to_save_type_invalid |
The private torch capture driver received a torch.Tensor instead of a layer selection (ArgumentTypeError, TypeError lineage) |
Bundle positional inputs into one tuple; use save= for selection |
intervention_predicate_type_invalid |
tl.trace or tl.record intervene is not callable (ArgumentTypeError, TypeError lineage on both entry points) |
Pass tl.when(...), another predicate, or None |
intervention_action_type_invalid |
Intervention action has an unsupported type | Pass a decision, helper, callable, or None |
intervention_direction_invalid |
tl.intervention.Rule was given the removed direction field (keyword or third positional): the site decides the pass (InvalidArgumentError) |
Edit a gradient with trace.do(tl.grad(site), edit, model=model, inputs=x, loss=fn), or stage it with trace.do(tl.when(tl.grad(site), edit), intervention=InterventionOptions(engine='set_only')) then trace.backward(loss); build Rule(tl.grad(site), edit) for the gradient and Rule(site, edit) for the activation |
intervention_rule_type_invalid |
Recipe clause is not an Rule (experimental) |
Build clauses with tl.when(...) and merge specs |
intervention_spec_type_invalid |
Recipe.merge() operand is not an Recipe (experimental) |
Build each clause with tl.when(...) before merging |
intervention_where_invalid |
tl.when(...) WHERE term is not a callable selector or predicate (experimental) |
Pass a selector (tl.func, tl.in_module, tl.site, tl.label) or predicate callable |
intervention_engine_invalid |
do(..., intervention=InterventionOptions(engine=...)) value is unknown |
Choose auto, replay, rerun, or set_only |
do_loss_not_callable |
do(..., loss=...) or tl.sweep(..., loss=...) got a value that is not callable (a tensor from the source trace would differentiate the wrong execution) (InvalidArgumentError; experimental) |
Pass a callable of the returned trace, e.g. loss=lambda t: t["output_1"].out.sum(); for backward options use result.backward(loss, retain_graph=True) |
do_loss_without_gradient_site |
do(..., loss=...) or tl.sweep(..., loss=...) was given but the plan has no gradient branch, so there is nothing for a backward pass to apply (InvalidArgumentError; experimental) |
Address a gradient with tl.grad(site), or drop loss= |
aggregate_loss_fn_required |
tl.stats.aggregate got a gradient metric key (tl.grad(site)) without loss_fn (InvalidArgumentError; experimental) |
Pass loss_fn=lambda out, y: ... (a scalar loss of the model output and the batch tail) |
extra_positional_input_invalid |
A tensor landed in trace's fourth positional slot (grad_transform) -- almost always an extra positional model input |
Bundle positional inputs into one tuple |
intervention_helper_unknown |
Built-in helper name is unknown | Choose a registered helper |
intervention_helper_renamed |
A saved intervention spec or pickled edit names the old spelling of a renamed builtin helper (resample_ablate renamed to scramble_elements; noise, project_off, affine_source, bwd_hook and the grad_* gradient edits renamed to add_noise, project_out and set_affine_coordinates; the bwd_hook and grad_* gradient edits have no helper any more and are written as ordinary edits on a tl.grad(site) address); there is no load alias, so it does not load (InvalidArgumentError; fields["renamed_to"] names the new helper) |
Rebuild the edit with the helper fields["renamed_to"] names (same arguments, same bytes) and save it again |
intervention_helper_arguments_invalid |
A saved intervention spec or pickled edit calls a builtin helper with arguments its current constructor does not take, because it was saved by a torchlens whose helper keywords differ; or a saved element-masked builtin edit stores a malformed mask (not a dense bool tensor), a mask without its mask_sha256 (or the reverse), or a mask whose bytes no longer match mask_sha256 (InvalidArgumentError, argument names the field) |
Load the spec with the torchlens version that saved it, or rebuild the edit with the current constructor and save it again; for a stored mask, re-save from the session that built it: fork.do(tl.units(site, mask), edit) then tl.io.save_intervention(fork, path, level='portable') |
facet_selector_fanout |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): an unscoped facet selector such as tl.head(5) writes more than one site; fields["site_count"] carries the number; a head scoped to one module writes its q, k and v silently (experimental) |
Scope it with .in_module(address) or name one facet |
scripted_function_not_captured |
WARNING code (CaptureGapWarning, contract row in docs/reference/warning_contract.md): a witness gap whose call-site line calls a TorchScript function that was not recorded as a jitscript boundary op (an in-place write into a tensor argument, or no call hook on this torch build); names the function and its call line; once per session; no verdict moves (experimental) |
Set PYTORCH_JIT=0 before the model's code is imported |
dlpack_call_not_captured |
WARNING code (CaptureGapWarning, contract row in docs/reference/warning_contract.md): a witness gap whose call-site line hands a tensor out through DLPack; names the call line; once per session; no verdict moves (experimental) |
Read the capture as a lower bound, or compute that step with torch operations |
intervention_over_invalid |
mean_ablate(dim=) is outside the mean vocabulary of None, an int, a tuple of ints or "members" with a Population source (InvalidArgumentError; fail-closed -- an accepted-but-ignored token would record a policy the hook does not compute, and a typo used to silently flip is_batch_independent open) |
Pass dim=None for the mean over every axis or the explicit integer axes to average; source=<tensor> or source=<Population> averages something other than the site, and dim="members" is the Population's elementwise member mean |
axis_semantics_unknown |
An axis-consuming stochastic/population edit had no derived-or-explicit axis: the ladder is explicit axis= > facet/recipe-declared semantic role > registered model/site metadata > this refusal, and an axis is never inferred from rank (on stock nn.TransformerEncoderLayer axis 0 is TIME) (edits; every spelling experimental) |
Pass the explicit integer axis (or tuple of axes) for the site's geometry |
chunked_capture_option_conflict |
chunk_size= was combined with a capture option it cannot compose with (keyword inputs, backward_ready, save_grads, hooks=, intervene=, stop_after=, or streaming storage=); refused before the forward (ChunkedForwardConfigError) |
Use the alternative the message names, or run without chunk_size |
chunked_forward_batch_coupled |
A chunked capture (chunk_size=) met a forward that needs the whole batch: either chunk assembly found an activation that is not row-wise over the batch, or the model's own forward failed on a partial batch (the cause is chained); fields["chunk_index"] names the chunk, and a chunked capture cannot stand for the whole batch (ChunkedForwardConfigError) |
Run without chunk_size |
chunked_replay_batch_coupling |
A batch-coherent edit (permute_batch, self-sourced mean_ablate) was attached to a trace captured in forward chunks: each fire would see one CHUNK and treat it as the whole batch (edits) |
Re-capture without chunk_size, or use a per-row edit (resample_rows_from) |
compose_empty |
compose() received zero edit leaves (edits) |
Pass the edits to chain, left to right |
compose_leaf_failed |
A composed leaf raised or returned a non-tensor at fire time; the whole fire aborts atomically, named compose[i] (edits; HookValueError) |
Fix the named leaf (it must return a tensor for the next leaf to consume) |
compose_leaf_invalid |
A compose leaf is not an executable helper spec (bare callables have undeclarable kind/flags/seed posture; audit-only specs have no factory) (edits) |
Compose declared helper specs; stage callables separately, one do call per callable on the same site |
compose_shape_change_unsupported |
A compose leaf declares allow_shape_change; v1 refuses ANY shape-changing leaf (the next-leaf-declares-contract rule is the documented relaxation) (edits) |
Apply the shape-changing edit alone, outside the chain |
compose_unseeded_stochastic |
A compose leaf is stochastic and unseeded; the honest-draw law admits no unacknowledged RNG into a chain (edits) |
Seed the named leaf explicitly (or seed='auto' on the derived-seed family) |
direction_vector_invalid |
set_direction_mean direction is not a finite, nonzero-norm 1-D tensor |
Pass the direction as a finite 1-D vector over the feature axis |
mask_not_row_equivariant |
A row-coherent edit (permute_batch, resample_rows_from) received a partial mask whose selected elements differ across batch rows; the v1 legality check is DRAW-INDEPENDENT (all rows share one non-batch mask) so a seed sweep can never flip it (edits) |
Select the same positions in every row, or split the batch into equal-mask groups |
permute_batch_extent_invalid |
permute_batch fired on a batch axis of extent < 2: permuting one row is a guaranteed no-op wearing an intervention's name (edits) |
Run a batch with >= 2 examples, or drop the edit |
population_agreement_empty |
No population member agrees with the subject's key (or the population carries no datums for a conditioned draw); the EPHEMERAL message names the requested key and available class sizes -- persisted records carry digests and counts only (edits) | Pick a matching= datum whose class has members, widen agree_on, or rebuild with data= |
population_datum_count_mismatch |
Population data= (or per-row matching=) datum count disagrees with the member/batch-row count |
Pass exactly one datum per member (or per subject batch row) |
population_digest_unavailable |
population(traces, digest_population=True) found no retained payload on any member: a content digest over nothing would stamp digest_kind="content" on an address identity (fable51 audit AUD-CODE 2.1) |
Capture the donor traces with the donor sites saved (save= covering them), or drop digest_population= to record the address identity |
population_empty |
A population was built with zero members | Pass a non-empty tensor stack, member sequence, or trace sequence |
population_heterogeneous |
Tensor population members disagree in shape or dtype; a donor population is one homogeneous stack | Build one population per geometry |
population_matching_invalid |
Half an agreement condition (agree_on=/group_by= without matching= or vice versa), an ambiguous bare sequence datum, or per-row datums passed to a whole-event verb |
Pass both halves; wrap datums explicitly (OneDatum / PerRowDatums) |
population_origin_required |
A population was built without a non-empty origin=: a population without recorded provenance is an unreproducible result (edits; the tl.subspace precedent) |
Describe the provenance, e.g. origin="clean run, templated prompts" |
population_reduce_underdetermined |
A population reduction resolved too few eligible members (e.g. std over fewer than 2) (edits) |
Widen the agreement condition or add members |
population_reduce_unsupported |
A tensor reduction was requested on a trace-backed population (donor values resolve per-site at fire time; there is no single tensor stack) | Build the population from site tensors |
population_source_invalid |
The population source is not a tensor stack, tensor sequence, or trace sequence -- or a verb needing the population noun received something else (edits) | Build the population first with the population constructor (origin= required) |
sampling_agreement_class_singleton |
WARNING (not a refusal): an agreement class of size 1 makes every draw return the same donor -- a deterministic patch wearing a sampler's name (edits) | Widen the agreement condition or add members; strict=True refuses instead |
sampling_agreement_class_too_small |
An agreement class of size 1 under strict=True: a single-donor "sample" is a deterministic patch wearing a sampler's name (edits) |
Widen the agreement condition, add members, or drop strict= to proceed disclosed |
sampling_geometry_mismatch |
An event-geometry proof failed (edits): a whole-site donor must match the target shape exactly, a row donor the target shape minus the proved batch axis, a population mean must broadcast, a direction must carry the feature-axis extent, or an axis is out of range -- the refusal prints both shapes and the axis proof; there is no elementwise fallback (that is scramble_elements, deliberately a different verb) |
Align the population/direction with the site geometry named in the message |
sampling_seed_required |
A stochastic verb was called without seed=<int> or seed='auto'; unacknowledged stochasticity never reaches a hook (an implicit global-RNG draw is silently re-rolled by later unrelated edits) (edits) |
Pass an explicit integer seed, or seed='auto' |
sampling_share_draw_invalid |
share_draw= is outside the closed per_firing/per_rule/per_group vocabulary (edits) |
Pass one of the three recorded draw-sharing policies |
sampling_trace_seed_unavailable |
seed='auto' needs the capture's recorded trace.options.seed and this door's run context does not carry one (edits) |
Pass an explicit integer seed, or run on a door that carries the capture seed |
selection_batch_cross_kind |
A selection-batch do() mixing ACT with PARAM/EDGE selections ran on an engine other than replay; PARAM and EDGE edits apply on the replay engine only, so the batch cannot run as one transaction there (on replay a cross-kind batch is atomic) (edits) |
Pass intervention=tl.options.InterventionOptions(engine='replay'), or apply the ACT pairs in their own do() call on that engine |
selection_batch_leaf_unsupported |
A selection-batch pair addressed leaf sites (inputs/buffers), which commit-then-propagate per site and cannot join one hook transaction in v1 (edits) | Batch interior sites only; apply leaf edits through single-selection do() |
selection_batch_pair_invalid |
A selection-batch do() input is malformed: a second edit argument beside the pair list, or a batch mixing Selections with legacy selector sites (two engines under one call) (edits) |
Pass only [(selection, edit), ...] pairs, every first slot a Selection |
jax_control_flow_invalid |
JAX control-flow mode is unknown | Choose reject, unroll, or region |
layer_pass_ambiguous |
Per-pass field read on a multi-pass layer | Access the field on one pass via .ops[k] |
layer_site_ambiguous |
A single site key was asked of a layer spanning multiple structural sites (extraction site metadata, the site invariant) (experimental) | Read the per-pass key via .ops[k].graph.site_key |
link_format_invalid |
Source-link format is unknown | Choose terminal, html, or text |
jax_unroll_range_invalid |
JAX unroll limit is below one | Pass a positive integer |
jax_unroll_type_invalid |
JAX unroll limit is not an integer | Pass a positive integer |
lit_attention_unsupported |
LIT bridge attention= argument: LIT deleted its attention-visualization panel upstream (2024-06-20), so an AttentionHeads field would serialize into a void no panel renders (experimental, as is every lit_* code) |
Use torchlens facets/visualization for attention; expose activations via sites= instead |
lit_blocks_preset_unavailable |
sites="blocks" found no single homogeneous repeated-module stack on the probe trace (none, or an unresolvable same-size same-depth tie); candidates ride the message and exc.fields["candidates"] |
Pass explicit module addresses via sites=(...) |
lit_capture_incomplete |
A LIT predict-time capture settled non-COMPLETE; rows are never fabricated from a partial capture (RecordBindingError) |
Inspect trace.outcome and re-run |
lit_dependency_missing |
tl.bridge.lit factory called without lit_nlp installed (MissingDependencyError; the install command rides exc.fields["install"]) |
pip install torchlens[lit] (isolated environment recommended) |
lit_labels_invalid |
labels= disagrees with the model config's class count, or no vocabulary is available at all |
Pass exactly one label per class in class-index order |
lit_model_output_unsupported |
The task adapter cannot read logits from the model output (no tensor / .logits / first tuple element, or wrong rank) (RecordBindingError) |
Serve a model whose output exposes [batch, num_labels] or [batch, seq, vocab] logits |
lit_pooling_invalid |
pooling= is neither a named strategy (mean_masked / first_token / last_unmasked) nor a callable |
Pass a named strategy or (tensor, attention_mask) -> [batch, features] |
lit_pooling_unsupported |
A site payload is outside the pooling contract (non-tensor, unsupported rank, geometry not leading with [batch, tokens], or a bad custom-callable result) (RecordBindingError) |
Select a [batch, ...] tensor site of rank 2-4, or pass a custom pooling callable |
lit_salience_unavailable |
salience=True but the model's input-embedding module cannot be resolved through get_input_embeddings() |
Expose the HF convention or construct with salience=False |
lit_site_ambiguous |
An explicit unqualified sites= entry names a module that fires multiple times per forward; explicit sites carry their pass in the key or refuse (LIT-panel) |
Use the pass-qualified spelling "address:N" named in the message |
lit_site_key_drift |
A predict-time trace did not reproduce a pinned structural site (zero or multiple (site_key, pass) matches); site_key is root-relative, so a wrapper-class change or module-tree rename lands here rather than silently rebinding (RecordBindingError) |
Rebuild the LIT wrapper for the current model object |
lit_site_unresolvable |
A sites= entry matched no module-output op on the probe trace |
Pass a module address from the traced module tree (samples ride the message) |
lit_sites_unspecified |
LIT bridge factory called without sites=; the bridge never guesses which activations to expose (the [UI-SPRINT] DEFAULT-SITES refusal branch) |
Pass sites="blocks", explicit addresses, or sites=() |
lit_task_invalid |
task= is outside the closed v1 vocabulary |
Pass "classification" or "causal_lm" |
lit_tokenizer_invalid |
The tokenizer is missing, not callable, or exposes neither pad_token_id nor eos_token_id (ragged LIT requests cannot be padded; the bridge never mutates the tokenizer) |
Pass the checkpoint's tokenizer with a pad or eos token |
lit_trace_not_executable |
tl.bridge.lit.model() received a finished Trace (or other non-module); LIT calls predict() on NEW inputs — edited text, counterfactuals — which a historical trace cannot execute (ArgumentTypeError) |
Pass the live nn.Module and tokenizer |
load_path_symlink_rejected |
The final component of a load path (the bundle directory, or its manifest, metadata or blobs entry) is a symlink; only that component is checked (path.is_symlink()), so a symlinked parent directory passes, and Trace.save, storage=tl.to_disk(...) and save_intervention apply the same final-component rule to their targets; a finalized fastlog bundle's manifest.json, fastlog_index.jsonl, pass_index.json, label_index.json or metadata.json refuses with it when it is a symlink or not a regular file (a FIFO or device), so it is never read |
Pass the resolved real path |
logit_lens_head_unavailable |
No module in the trace exposes the unembed_weight facet or a vision head facet (classifier_weight, image_projection_weight), or a vision head's single-token read was not identified, so the model's own lens cannot be reconstructed (LogitLensError, RuntimeError lineage; experimental) |
Register a facet recipe producing the language_model_head facet names for the architecture (tl.facets.register), or pass lens= explicitly |
logit_lens_hidden_rank_invalid |
A vision head lens reads one token of a [batch, sequence, hidden] state, but the projected facet is not rank 3 (experimental) |
Project a block residual facet such as resid_post, or pass lens= |
logit_lens_identity_invalid |
A user lens's model_identity is not a model-identity record (a mapping with a level entry), or its measured record names a hash outside blake2b / sha256 (experimental) |
Attach the unmodified record from manifest["signature"]["model_identity"], or drop the attribute |
logit_lens_identity_mismatch |
A user lens's recorded measured model identity differs from the traced model's state digest, or its per-layer callables carry different identity records; its rows would be a confident reading of a different model (experimental) | Use a lens built for this model, or pass validate=False to apply it anyway |
logit_lens_identity_unrecorded |
WARNING (not a refusal): a user lens has no comparable model identity and its last-layer decode does not reproduce the model's captured logits (or the check could not run); the lens still runs (experimental) | Attach the model's identity record as lens.model_identity, or pass validate=False to skip the check |
logit_lens_k_invalid |
logit_lens_predictions(k=...) received a non-positive top-k width (experimental) |
Pass k >= 1 |
logit_lens_layer_outside_head |
An explicit layers= entry lies outside the tower whose blocks feed the trace's vision head (for example a CLIP text-tower block under the image head), so the head's lens cannot decode it (experimental) |
Pass layers inside the head's tower, or pass lens= for those layers |
logit_lens_position_invalid |
A positions= entry normalizes outside the full sequence length (experimental) |
Pass positions inside [-length, length) |
logit_lens_projection_rank_invalid |
A layer's projected logits have rank below 2, so per-position prediction extraction is impossible (experimental) | Pass a lens= returning at-least-rank-2 logits for that layer |
logit_lens_token_id_invalid |
A tokens= id lies outside the projected vocabulary (experimental) |
Pass token ids inside [0, vocab) |
logit_lens_mask_input_unavailable |
logit_lens_predictions(mask_input=True) needs the trace's first model input to be a saved integer token-id tensor with one row per batch row, and this trace's is not (a model fed embeddings has no token ids to ban) (LogitLensError; experimental) |
Trace the model on token ids (tl.trace(model, input_ids)), or drop mask_input=True |
mi_target_unresolvable |
The mech-interp kit could not anchor its decomposition target: no unembedding head, a failed final-norm dataflow walk, an unknown target= label, or no additive residual merge upstream of the target (MechInterpError, RuntimeError lineage; every mi_* spelling experimental) |
Pass an explicit target= op label on the residual stream, or capture with the stream saved |
mi_spine_open |
The execution-order accumulation of literal writers does not reproduce a captured spine state bitwise, so the stack is OPEN (mikit; per-dtype degrade clause applies off fp32/CPU) | Pass strict=False for a diagnostic-only stack with an unresolved_remainder row (rejected by DLA/gallery), or report the architecture frontier |
mi_spine_ambiguous |
A spine join's membership could not be decided by the ancestry test (both operands additive, neither provably the stream), or the disambiguating search exceeded its bound | Decompose from an explicit target=, or report the architecture (a certifiable-topology frontier) |
mi_payload_missing |
A kit function needs op payloads that were not saved; the refusal carries the COMPLETE missing-site set (never a partial table, never a silent recapture) | Recapture with the disclosed retention plan's predicate as save=, or save='all' |
mi_stack_empty |
A component stack has no rows to accumulate | Produce the stack from a trace with at least one proven writer |
mi_stack_shape_mixed |
Component rows have mixed shapes and no target value to broadcast against | Read rows individually via .rows, or produce the stack from a payload-bearing capture |
mi_top_by_invalid |
top() received an unknown reduction |
Pass by="norm" |
mi_pandas_unavailable |
to_pandas() needs the optional pandas dependency |
pip install pandas, or read .rows / .labels directly |
mi_projection_unresolvable |
No 2D-weight parameter inside the attention module is a dataflow ancestor of the q/k/v/attn_out facet op (external-kernel projections are a named frontier) | Capture with default options so projection ops are recorded |
mi_orientation_unknown |
A projection/unembedding weight's storage orientation cannot be decided (unknown module class with a square weight -- the confusion behind the measured 18.80 per-head error) | Report the module class so its orientation can be pinned; Conv1D and Linear families are known |
mi_qkv_slicing_unprovable |
A fused QKV weight's role slice has neither recipe-transform nor captured-split evidence; hardcoding a q|k|v order is exactly what this refusal prevents | Capture with default options so the QKV split ops are recorded |
mi_weight_view_unverified |
A derived head-indexed weight view fails to reproduce the captured projection output (wrong orientation, slice order, or convention) | Report the module class/architecture; the view is refused rather than served wrong |
mi_head_geometry_unavailable |
An attention module lacks the head facet vocabulary (result/attn_out/n_q_heads/d_head), or a layers= selector misses | Capture with the builtin attention recipes active; attention-free architectures have no head rows |
mi_position_unmappable |
A requested position cannot be mapped between the residual stream and the logits tensor (the logits_to_keep slice is ACTIVE under generation), or lies out of range |
Trace a plain forward, or select positions the recorded logits_position_map can translate |
mi_token_id_invalid |
An answer=/vs= token id lies outside the vocabulary, or answer/vs lengths mismatch | Pass in-vocab ids; logit diffs are pairwise |
mi_stack_not_admissible |
DLA was fed a diagnostic (strict=False) or CLOSED-UNRESOLVED stack, or a stack with no target value; such stacks are diagnosis, not attribution (mikit) |
Fix the capture so strict decomposition closes, or decompose a different target |
mi_dla_identity_failed |
The in-API DLA identity sum(rows) + constant == captured native logits missed beyond the cancellation-aware tolerance -- a kit or capture defect, never served as a table |
Report with tl.report.doctor(model, x) |
mi_norm_scale_mode_invalid |
apply_norm_scale(scale=...) received an unknown mode |
Pass scale="frozen" (additive) or scale="component" (non-additive diagnostic) |
mi_translation_generation_unknown |
alias_report(generation=...) names a generation with no translation rows |
Pass generation="2.x", "3.x-bridge", "4.x", "nnterp" or "interp-engine" |
mi_analysis_unknown |
retention_plan(analyses=...) names an unknown analysis |
Choose among accumulation / decomposition / dla / heads / head_scores / prompts |
mi_token_ids_unavailable |
Token-equality head-score masks found no captured integer input matching the pattern's sequence length | Trace the model on token ids with the input op saved |
mi_head_score_kind_invalid |
head_scores(kind=/measure=) received an unknown taxonomy kind or measure |
Choose kinds previous_token / duplicate_token / induction; measures mul / abs |
mi_head_score_period_invalid |
FixedPeriodInduction(period=) got a period that is not a positive int (experimental) |
Pass FixedPeriodInduction(period=<the repeated sequence's length>), or kind='induction' for the token-equality mask |
mi_tokenizer_required |
test_prompt got a text prompt without a tokenizer |
Pass tokenizer=, or pass token ids directly |
mi_grid_engine_unsupported |
patching grid engine="replay" is reserved until the known HF replay crash (FIX-A) lands; unknown engines also land here |
Use engine="rerun" (the receipted live-hook route) |
mi_grid_axes_invalid |
Grid axes outside {layer, position, head}, missing the layer axis, or a head axis on a facet with no known head layout | Pass axes such as ("layer", "position"); head grids need head-carrying facets (z/result/pattern/q/k/v) |
mi_grid_budget_exceeded |
The grid's cell count exceeds the hard budget= ceiling (cost is disclosed BEFORE any rerun) |
Narrow layers/positions/heads, or raise budget= explicitly |
mi_grid_length_mismatch |
Clean and corrupted facet shapes differ; grids never broadcast across prompts | Pad or re-tokenize so both prompts have equal length |
mi_lowered_site_not_lowerable |
A q/k edit cannot lower to the post-projection site (softmax intervenes), or the lowering kind is unknown | Recapture with attn_implementation="eager" and edit the real q/k projection outputs; kinds are head / pattern |
mi_lowered_dropout_active |
Lowered counterfactuals are eval-mode only (in-kernel SDPA dropout is unreproducible) | model.eval() before lowering |
mi_lowered_length_mismatch |
Clean/corrupt z or pattern shapes differ; lowered cells never broadcast | Use equal-length prompts |
mi_grid_all_identical |
WARNING (not a refusal): every patching-grid cell produced an identical metric; a genuinely flat effect is a finding, so the grid discloses instead of refusing (mikit) | Check the fire receipts and the metric before publishing a null result |
mi_lowered_stale_facet_read |
A virtual attention facet at the lowered layer was read on the patched rerun; the lowering landed at the real post-projection site and the virtual interior was never recomputed -- the trace refuses rather than lies | Recapture eager and edit z/pattern directly, or read other layers / downstream sites |
mi_factored_shape_mismatch |
A FactoredMatrix construction or product received factors whose inner dimensions differ or whose leading dimensions do not broadcast, or BA was asked of a non-square product (vendored TransformerLens algebra; experimental) |
Match the inner dimensions (A[..., l, m] with B[..., m, r]) and keep the leading dimensions broadcastable |
mi_factored_scalar_invalid |
FactoredMatrix * x received a tensor with more than one element (experimental) |
Use @ for matrix multiplication; * takes a scalar |
mi_neuron_geometry_unavailable |
mlp_neuron_contributions found no MLP exposing the down-projection vocabulary (down_out/output), no 2D weight inside the named MLP, or a layers= selector missed (experimental) |
Capture with the builtin MLP recipes active and pass an MLP module index or address |
mi_neuron_index_invalid |
A neurons= entry is not an integer index inside [-d_mlp, d_mlp) (experimental) |
Pass integer neuron indices inside the MLP width |
mi_kv_expansion_unavailable |
patch_query_heads_grid found no captured op that expands an attention module's grouped key/value tensor to the query heads: a fused kernel expands inside the kernel (torch scaled_dot_product_attention with enable_gqa=True), so no query head's copy exists to patch (experimental) |
Load the model with attn_implementation="eager", or switch it to the registered "torchlens" attention backend (tl.bridge.transformers.register_attention(model)) |
mi_kv_expansion_ambiguous |
patch_query_heads_grid found more than one expansion op for one module's key/value tensor, the op has no single counterpart in the corrupted trace, or one rerun fired the interceptor other than exactly once; patching one copy would leave another unpatched (experimental) |
Patch the whole group with mechinterp.patch_grid(..., sites="v", axes=("layer", "head")), or use equal-length prompts that take the same path |
mi_kv_heads_not_grouped |
patch_query_heads_grid ran on attention whose query and key/value head counts are equal, so no key/value tensor is shared and there is nothing to intercept (experimental) |
Use mechinterp.patch_heads_grid, which measures each head directly |
mi_edge_graph_nonadditive |
component_graph found a residual stream that is not additive under its decomposition: a writer that is not an embedding, an attention head or an MLP (a renormalized or rescaled stream), a receiver that does not read the stream through exactly one pre-norm, an attention write that differs from its captured attn_out, or an attention remainder that is neither the output bias nor zero (experimental) |
Use a pre-norm additive-residual model, or decompose one state with torchlens.mechinterp.residual_decomposition(trace, target=...) |
mi_edge_graph_open |
component_graph's in-API identity failed: a receiver's captured pre-norm input differs from the sum of its incoming edge contributions beyond the reconstruction tolerance (experimental) |
Report the architecture: a writer the graph does not model reaches that receiver |
mi_edge_graph_gqa_unsupported |
component_graph ran on grouped-query attention (fewer key/value heads than query heads); the k and v receiver vocabulary for shared key/value heads is not defined yet (experimental) |
Use torchlens.mechinterp.attention_head_contributions(trace) for per-head writer rows on that model |
mi_edge_patch_edge_repeated |
patch_edges got the same edge more than once; each edge is patched at most once, and a repeat would subtract its sender twice (experimental) |
Pass each edge once, for example list(dict.fromkeys(edges)) |
mi_edge_scores_setting_invalid |
edge_scores got an unknown method, steps that is not a positive integer, steps with method='eap', or an unknown example_reduction (experimental) |
Pass method='eap_ig' with steps=5 (the defaults), or method='eap' without steps; example_reduction is 'mean' or 'sum' |
mi_edge_scores_metric_invalid |
edge_scores's metric did not return a real tensor with one value per example (or one scalar), or does not depend on the logits it is given (experimental) |
Return per-example values from the logits argument, for example logits[:, -1, correct] - logits[:, -1, wrong] |
mi_edge_scores_inputs_mismatched |
edge_scores's corrupted inputs give a node (or a receiver input) of another shape than the clean inputs (experimental) |
Pass corrupted inputs with the clean inputs' batch size and token count per row |
mi_edge_scores_shared_norm |
One norm feeds two receiver modules (attention and MLP), so a per-receiver gradient cannot be read at its output (experimental) | Use a model whose attention and MLP read the residual stream through their own norms (GPT-2, GPT-NeoX/Pythia, Llama-class) |
mi_edge_scores_input_unresolvable |
The first embedding write into the residual stream is not its embedding module's output, so EAP-IG has no capture-time site to shift the input node (experimental) |
Use method='eap', or a model whose embedding modules write the residual stream directly |
mi_faithfulness_curve_invalid |
circuit_performance_ratio / circuit_model_difference got fewer than two points, a value count that does not match the fractions, non-finite values, fractions that do not strictly increase, a mapping together with fractions=, or log_scale=True with a non-positive fraction (experimental) |
Pass one finite value per strictly increasing fraction (the ten MIB fractions by default) |
mi_edge_selection_unresolvable |
A component edge's write site could not be addressed: no single op edge carries the receiver's pre-norm input into its norm, or the projection output behind a q/k/v receiver was not recomputed (experimental) | Capture with save='all', capture=tl.options.CaptureOptions(replayable=True) and rebuild the graph from that trace |
norm_eps_unavailable |
A norm reconstruction found no epsilon metadata on the norm module; the kit never guesses eps (NormReconstructionError, RuntimeError lineage; experimental) |
Capture with a recipe disclosing eps/variance_epsilon, or register a facet recipe for the norm class |
norm_geometry_mismatch |
A norm reconstruction's input and output shapes disagree, so the linearization has no operating point | Anchor the norm's input through the dataflow walk before reconstructing |
norm_convention_unmatched |
No known norm convention (LayerNorm/RMSNorm/affine-free, centered or not) reproduces the captured norm output; nonstandard conventions (e.g. Gemma-style (1 + weight)) need their own recipe convention. The recompute runs in the accumulation dtype (fp32 for fp16/bf16 payloads), rounded once and compared in the payload dtype, so a half-precision refusal is a convention mismatch, never a precision artifact |
Register a facet recipe evidencing the norm's convention; the kit never guesses. On fp16/bf16 payloads the remedy also names the accumulate/round-once comparison and the RECONSTRUCTION_ULP_HEADROOM row applied |
lookback_invalid |
Lookback is not an integer in [0, 1024] |
Pass an in-range integer |
lookback_payload_policy_invalid |
Lookback payload policy is unknown | Choose a documented payload policy |
lookback_payload_policy_conflict |
tl.followed_by(...) under lookback_payload_policy='metadata_only', which retains no candidate payloads (PredicateError, RuntimeError lineage) |
Pass a payload-retaining lookback policy such as 'detached_raw' |
fastlog_index_too_large |
Fastlog recovery index exceeds the byte ceiling | Treat as a hostile/implausible bundle; re-record |
manifest_missing |
Bundle directory has no manifest.json |
Pass the bundle directory produced by trace.save() |
manifest_not_json_object |
Manifest root parses but is not a JSON object (also validate_tlspec) |
Re-save the artifact; do not hand-edit the manifest |
manifest_schema_invalid |
Manifest parses as a JSON object but violates the bundle schema (missing/mistyped field, forged entry, count mismatch) | Re-save the artifact with trace.save(); do not hand-edit the manifest |
record_schema_invalid |
A saved format 3 record cell fails its typed schema (wrong kind, unknown $tl tag, tag payload missing a field, a name outside its table, a row reference out of range); the message names record, row and column |
Re-save the artifact with trace.save(); do not hand-edit record files |
manifest_unreadable |
Manifest cannot be read or does not parse within bounds (also validate_tlspec) |
Check permissions/integrity; re-save if truncated |
manifest_write_failed |
manifest.json could not be written during save |
Check disk space and directory permissions, then re-save |
model_door_binding_refused |
A TorchLens model door (tl.trace, tl.release_model, ...) received a bound intervention executor under OP2 arm (a): doors never silently treat a binding as a plain model; the refusal prints the canonical spelling (experimental) |
Pass binding.model as the model and binding.recipe as intervene=, or run the capture-free lane by calling the binding |
model_door_intervene_conflict |
OP2 arm (b) normalization would have to merge a binding's spec with the door's explicit intervene= operand; the funnel never merges two spec sources silently (experimental) |
Merge the specs explicitly and pass one spec, or pass the plain base model |
model_door_policy_invalid |
The OP2 door-policy switch received a value outside the closed refuse/normalize set (experimental) |
Pass 'refuse' (arm a) or 'normalize' (arm b) |
meta_kernel_unavailable |
An op with no meta kernel died inside torch dispatch during structure-only capture (MetaKernelUnavailableError; original chained) |
Run a real capture, or upgrade torch for broader meta-kernel coverage |
metadata_object_count_exceeded |
metadata.pkl opcode count exceeds the allocation ceiling |
Treat as a hostile/implausible artifact; re-save from source |
metadata_payload_not_a_mapping |
metadata.pkl payload is not a metadata mapping |
The artifact is corrupt or hand-edited; re-save with trace.save() |
model_explorer_diff_pair_invalid |
model_explorer_diff needs exactly two captures (a two-member Bundle or a (subject, reference) pair) (experimental) |
Pass exactly two traces or a two-member Bundle |
model_explorer_duplicate_node_id |
A Model Explorer graph minted duplicate node ids; the viewer keeps the first and SILENTLY drops the rest with their edges (id-minting tripwire, should never fire) | Report as a TorchLens bug with the trace summary and graph id |
model_explorer_episode_join_mismatch |
The episode step-membership joins disagree (module-call ops list vs module-stack cross-check); exporting either silently would misattribute ops | Report as a TorchLens episode-capture bug with the call label |
model_explorer_episode_ledger_unavailable |
The episode ledger is missing its stepped-module address, rows, or a ledger-named module call; per-step export cannot derive membership | Re-capture the episode, or export with per_step=False |
model_explorer_namespace_malformed |
A module call stack breaks root-first prefix continuity under strict_namespace=True (the default degrades to the longest verified prefix, disclosed namespace_fidelity=partial) |
Export with strict_namespace=False and report the malformed stack |
model_explorer_overlay_callable_error |
A user overlay callable raised while resolving a node value (original chained) | Fix the callable to return a numeric value or None per node |
model_explorer_overlay_public_conflict |
A value-derived overlay provider (magnitude/grad_norm/nan) was requested under privacy_profile='public', which drops value-derived data by construction |
Export with privacy_profile='local', or drop the provider |
model_explorer_overlay_value_invalid |
An overlay provider resolved a non-numeric value; a string would silently render as a broken heatmap | Make the source resolve to numbers or None (omit) |
model_explorer_parent_unresolvable |
A recorded parent reference resolves against neither label spelling in its graph; emitting would silently drop the edge in the viewer | Report as a TorchLens capture-relation bug with the op label |
model_explorer_payload_invalid |
Strict semantic validation failed (duplicate ids, dangling edges, missing group rows, duplicate graph ids); the payload would be silently lossy in the viewer | Inspect fields['failures'] and report the failing graph |
model_explorer_privacy_profile_invalid |
privacy_profile is outside the closed local/public vocabulary |
Pass privacy_profile='local' or 'public' |
model_explorer_serve_unavailable |
Serving needs the Model Explorer app package, which is not installed | pip install "torchlens[model-explorer]" (the extra installs ai-edge-model-explorer>=0.1.33,<0.2) |
model_explorer_value_not_retained |
A value-derived overlay provider resolved zero values (structure-only capture or a save policy that retained nothing it needs); export never widens the save policy or runs backward | Re-capture with the needed retention, or drop the provider |
model_type_unsupported |
Torch capture/validation root is not an nn.Module or a bound method of one (the ruled root contract): closures, bare functions, and other callables refuse at tl.trace and tl.validate, teaching the ruled spelling |
Pass a torch.nn.Module, or a bound method of one (owner via method.__self__, e.g. tl.trace(model.generate, input_ids)), or select the backend that owns the model |
model_wrapper_uninstrumentable |
Model is a transformer_lens TransformerBridge, whose __setattr__ redirects assignment so capture instrumentation cannot land (UninstrumentableModelWrapperError) |
Reload the HF model fresh and trace it instead of the bridge (or trace a HookedTransformer while you still use one) |
max_pairs_invalid |
Bundle diff pair budget is below one | Pass max_pairs >= 1 or None |
max_predicate_failures_invalid |
Predicate failure budget is not a non-negative int | Pass a non-negative integer |
module_focus_empty |
Focused module contains no rendered layers | Focus a module with layers |
module_focus_invalid |
Module focus value has the wrong kind or owner | Pass an owned Module or address string |
module_focus_not_found |
Module focus address is not in the trace | Pass an existing module address |
metric_name_invalid |
Intervention metric name is unknown | Choose a registered metric or callable |
metric_shape_mismatch |
Metric operands have different element counts, or a Bundle comparison's aligned site holds different shapes in the two members (the refusal names the site) | Pass equal-size operands; compare members whose aligned sites hold the same shape (for runs on different inputs, inputs of the same shape, such as prompts with the same token count) |
metric_tensor_type_invalid |
Metric operand is not a tensor | Pass tensor operands |
metric_type_invalid |
Metric selector is neither a name nor callable | Pass a registered name or callable |
module_call_ambiguous |
Single-call accessor on a multi-call module | Access one call via module.calls[N] |
facet_selector_module_multi_call |
A facet selector scoped with .in_module(addr) to a module that ran more than once; a facet write hooks the home op's layer, which fires on every call (InvalidArgumentError) |
Read one call's facets at its call-qualified address, trace['addr:1'].facets (the error's call_addresses field lists them); write through a selector scoped to a module that runs once |
facet_selector_no_match |
A bare facet selector (tl.head(...), tl.facet(name), tl.facet(name).latent(k)) read on a finished trace through trace[selector] matched no facet that any module or op record of this trace serves (SiteResolutionError) |
List the facets a record serves with trace[label].facets.keys() (the remedy names this trace's first label), then select one of them |
multipass_bare_label_ambiguous |
A bare layer label (exact string selector, tl.label, or do string target) addressed a multi-pass (recurrence-grouped) layer where one op is needed: every pass is a distinct op, and a single-op consumer must never guess a pass (AmbiguousSiteError; the teaching message names the layer, its pass count, every pass-qualified spelling, :last, :all and trace[label], the aggregate Layer; experimental). trace[label] itself returns the Layer. tl.units refuses the same case as selection_unresolvable / multipass_bare_label |
Address one pass with a pass-qualified label (label:pass or label:last), every pass with label:all (a Selection), or the aggregate Layer with trace[label] |
netron_attachment_invalid |
A netron attachment-sidecar row violates a vendor drop rule netron would swallow silently (unknown kind, missing/newline/unresolvable target, non-empty model/graph target, nameless item, per-target duplicate name), or attachment=True was passed without a real path= (netron) |
Emit rows satisfying the four writer guards (targets from the exported projection; target='' for model/graph scope; per-target-unique names), and pass path= with attachment=True |
netron_granularity_invalid |
Netron export granularity= is outside the closed op\|module\|rolled vocabulary, or depth= is not a positive int (netron; experimental) |
Pass granularity='module' (default), 'op', or 'rolled', and an int depth >= 1 |
netron_path_or_open_required |
tl.export.netron got path=None without open=True, leaving it nothing to do (netron) |
Pass a destination path, or open=True to serve the artifact from memory |
netron_serve_unavailable |
The netron one-liner (open=True) needs the netron package, which is not installed; the artifact FILE needs no extra (netron) |
pip install 'torchlens[netron]', or open the written file at netron.app / the desktop app |
netron_extent_budget_exceeded |
WARNING code (TorchLensWarning): a netron export's root graph exceeds the ~27-rank legibility budget (netron) |
Export with granularity="module", reduce depth=, or export a sub-module's trace |
netron_module_projection_fallback |
WARNING code (TorchLensWarning): the module projection produced a function-call cycle (a dead file in netron) and fell back to the valid op projection, disclosed in metadata (netron) |
Export with granularity="op" and report the trace |
neuro_dependency_conflict |
tl.neuro.rdms / tl.neuro.datasets (or the rsatoolbox bridge) was touched where rsatoolbox is installed but cannot import because an installed package holds scikit-learn below the 1.6 it needs: torchlens[neuro,brainscore] resolves, but brainscore-vision pins scikit-learn<1.6 and rsatoolbox 0.3 imports sklearn.utils.validation.validate_data (MissingDependencyError, AttributeError lineage; diagnosed from installed metadata without importing rsatoolbox, so the names leave __all__/dir() and hasattr answers False; both versions and the pinning package ride exc.fields; experimental) |
Install torchlens[neuro] and torchlens[brainscore] in separate environments; without brainscore-vision, pip install "scikit-learn>=1.6" |
neuro_matrix_invalid |
tl.neuro.rdms matrix mode was given an empty mapping, colliding keys, a non-square/asymmetric/non-zero-diagonal/non-finite matrix, fewer than 2 patterns, or matrices disagreeing on pattern count (NeuroHandoffError, ValueError lineage; every neuro spelling experimental) |
Pass unique string keys mapping to finite symmetric zero-diagonal n x n matrices over one shared stimulus set |
neuro_obs_descriptor_invalid |
A neuro handoff obs=/pattern_descriptors= column is not a mapping, collides with the reserved tl_presentation_index key, or its length disagrees with the stimulus/pattern rows -- a misaligned condition vector is plausible, scientifically wrong, and invisible downstream (NeuroHandoffError) |
Pass exactly one entry per row, in row order, under a non-reserved name |
neuro_pool_vocabulary_unavailable |
pool= was given a value: the shared extraction/readout preset vocabulary has not shipped and torchlens.neuro deliberately mints no pooling spellings (the readout is scientific provenance) |
Pass pool=None (disclosed flattening, recorded as pool="flatten") and apply readouts upstream at extraction time |
neuro_rdms_chunked_unavailable |
tl.neuro.rdms(chunked=...) was passed: the chunked execution seam is reserved for streaming-scale RDMs and launch is eager (neuro memo section 8) |
Drop chunked= |
neuro_rdms_measure_required |
tl.neuro.rdms matrix mode without dissimilarity_measure=: a bare matrix has forgotten its metric and rsatoolbox comparison code switches on that field |
Declare the measure the matrices were computed with |
neuro_rdms_mode_conflict |
tl.neuro.rdms mixed the two modes: source mode got a hand-typed dissimilarity_measure= (the computed label cannot lie), or matrix mode got metric=/sites=/pool=/obs= (nothing is computed or selected there) |
Use source-mode kwargs with a Trace/extraction source, or a bare mapping plus the declared measure |
neuro_site_ambiguous |
An explicit neuro site lookup named a recurrent layer with several passes; a bare layer lookup is ambiguous across passes (NeuroHandoffError; the message names every pass-qualified alternative) |
Request a pass-qualified site (e.g. "layer:2"), or omit sites= -- default sweeps emit pass-qualified keys automatically |
neuro_sites_inconsistent_rows |
The sites selected for one tl.neuro.rdms stack disagree on stimulus-row counts; one RDMs stack must share one pattern set |
Select sites from one capture with one stimulus set |
neuro_source_invalid |
A neuro handoff source is not a Trace, LoadedExtraction, or extraction-directory path -- or site=None (the final-output special case) was combined with a file-route source, which stores explicit output keys only |
Capture with tl.trace, or pass an extraction directory and name a stored output key |
neuro_stimulus_ids_mismatch |
stimulus_ids= disagrees with the stimulus rows: wrong length, or a disagreement with the ids recorded by the extraction artifact (recorded ids are authoritative; an explicit list acts as validation, never silent replacement) |
Pass one identifier per row in row order, drop stimulus_ids= to use recorded ids, or re-extract with the intended ids |
node_label_field_invalid |
Node label field name is unknown | Pass documented label field names |
npz_export_invalid |
torchlens.neuro.export_npz (experimental) received an unknown layout/compatibility combination, object arrays (interchange is numeric-only, allow_pickle=False), an empty site set, inconsistent per-site stimulus counts for the per-stimulus layout, or a stimulus_ids cardinality mismatch |
Use layout='consolidated'/'per_stimulus' (Net2Brain compatibility requires per-stimulus), numeric tensors, and one id per stimulus |
node_overlay_invalid |
Node overlay name is unknown | Choose a supported overlay |
op_lookup_index_out_of_range |
Integer layer index is out of range | Pass an in-range index |
op_lookup_not_found |
Lookup key matches no layer, op, or module | Use a valid label, index, or address |
op_lookup_pass_out_of_range |
Pass qualifier exceeds the recorded pass count | Specify a lower pass number |
op_lookup_pass_required |
Bare label names a multi-pass layer | Append a pass qualifier such as :2 |
on_forward_error_invalid |
Forward-error policy is unknown | Choose raise, attach_partial, or return_partial |
on_predicate_error_invalid |
Predicate-error policy is unknown | Choose auto, accumulate, or fail-fast |
plugin_activation_disabled |
Plugin activation was requested while the TORCHLENS_PLUGINS=none kill switch (or a literal-none project declaration) is in force; the kill switch beats every consent path |
Unset TORCHLENS_PLUGINS / remove the none declaration, then activate explicitly |
plugin_activation_invalid |
A provider's activation payload violated its door contract: a non-callable entry-point target (consent law: zero-arg factories only), a factory result that is not a BackendSpec, or a malformed export-target row |
Fix the provider to export a zero-arg factory returning the documented object for its group |
plugin_distribution_not_installed |
activate() named a distribution that is not installed; the message lists the installed providers |
Install the provider distribution, or activate an installed one |
plugin_group_door_unavailable |
The entry-point group's activation door has not landed in this torchlens build; refusal fires BEFORE any provider import | Use a landed group, or upgrade torchlens to a release that ships the door |
plugin_group_unknown |
Entry-point group is outside the closed torchlens plugin-group vocabulary (discovery and activation both refuse) | Use a documented torchlens.* entry-point group |
plugin_metadata_unreadable |
WARNING (not a refusal): one installed distribution's dist-info metadata could not be inspected during discovery; the group scan continued without it | Repair or reinstall the broken distribution named in the message |
plugin_provider_load_failed |
WARNING (not a refusal): non-strict activation skipped a broken provider and continued the batch; the record lands in the activation ledger as failed |
Fix or unpin the provider distribution; pass strict=True to raise instead |
plugin_strict_load_failed |
Strict activation of a provider failed; the provider's own exception is chained as the cause | Fix or unpin the provider, or pass strict=False to continue past broken providers with a warning |
predicate_default_invalid |
Default capture decision is neither bool nor CaptureSpec (PredicateError, RuntimeError lineage) |
Pass True, False, or a CaptureSpec as the default |
predicate_evaluation_failed |
Accumulated predicate exceptions surfaced at the end of a recording (PredicateError, RuntimeError lineage; exc.failures carries the tracebacks) |
Fix the predicate using the accumulated failure tracebacks |
predicate_return_invalid |
A save, intervene, or halt predicate returned a value outside its declared contract (PredicateError, RuntimeError lineage) |
Return a documented decision value from the predicate |
predicate_storage_conflict |
keep_grad=True conflicts with disk-only storage or an integer/bool payload dtype (PredicateError, RuntimeError lineage; the grad-slot twin raises InvalidStorageError) |
Keep the payload in RAM with a floating dtype, or drop keep_grad=True |
param_all_same |
FINDING (checks kit param_health, warning): every element of a non-trivial parameter/buffer holds one identical nonzero value — the suspicious constant-fill signature |
Inspect the named tensor's initialization / loading path |
param_all_zero |
FINDING (checks kit param_health, info): a parameter/buffer is entirely zero — legitimate for fresh biases/norm offsets, disclosed so a zeroed weight cannot hide |
Confirm the zero fill is intended for the named tensor |
param_bounds_violated |
FINDING (checks kit param_health, warning): a tensor's finite extrema left its caller-declared bounds |
Bounds are the caller's declaration; inspect the named tensor at the reported extrema |
param_dtype_headroom |
FINDING (checks kit param_health, warning): finite magnitudes within max_fraction of the dtype's finite maximum — the overflow-next-step signature (fp16 headroom) |
Lower the values (loss scale, clipping, init), or move the tensor to a wider dtype |
param_grad_nonfinite |
A live parameter gradient held NaN/Inf at the S-B pre-write site (post-clip, accepted step): the raise fires BEFORE the weights are written, so weights are bitwise clean and the batch is re-runnable; reports the culprit AND the clipping collateral count, attribution=smeared when clipping NaN-poisoned the norm (never names an innocent). Under a GradScaler this site is structurally unreachable (the skip fires first); at S-A the same evidence is collected, never raised (CheckViolationError; demotable per registration; the warn form carries the contract) |
Upstream, clip_grad_norm_(error_if_nonfinite=True) is torch's own tripwire (off by default); under fp16 use a GradScaler, which makes this event a harmless skipped step; forensics via tl.debug.bisect_nan / find_nan on a captured trace |
param_movement_decay_band |
FINDING (checks kit, info, collect-only): a parameter moved by approximately its decoupled weight-decay rescale alone this accepted step — consistent with (not proof of) receiving no useful gradient; corroborating fact only, measured to lag a real death by 22 to >32 steps | Read param_received_no_gradient for the zero-latency evidence |
param_received_no_gradient |
FINDING (checks kit): a watched parameter's grad was None / all-zero over a sustained M-of-N window of accepted steps (the primary detector: zero-latency where movement statistics lag by 22->52+ steps; single zero-grad steps are legitimate — MoE routing, untaken branches, embedding coverage — hence the window). Names a cone, not a culprit; the warn form carries the contract |
Follow the finding's follow_up to the repaired gradient_flow_audit module/is_frontier column, which names the exact dead layer |
param_subnormal_heavy |
FINDING (checks kit param_health, warning): the subnormal fraction of a tensor exceeded its threshold — the underflow/vanishing signature |
Inspect the named tensor's scale; consider a wider dtype or larger loss scale |
param_substitution_engine_unsupported |
do() over a PARAM selection on the rerun/set_only engines; parameter substitution ships on the replay engine only — the value each op consumes is substituted "as if" the parameter were changed, and the live parameter is never written (experimental) |
Run the parameter substitution on the replay engine (the default when no model/x is passed) |
param_substitution_occurrence_underivable |
A PARAM-selection do() could not address every consumption of the parameter: no matching top-level template component, a nested container position, a released/legacy capture without identity or barcode, a bare (pass-ambiguous) multi-pass consumer spelling, or a consumer inventory omitting a pass of a multi-pass layer — a partial substitution would be a silent wrong "as if". Recurrently reused params (tied weights, multi-pass consumers) ARE substitutable when every consumption is recorded pass-qualified (experimental); or a tl.param(...) selection naming a registered buffer has no saved initial version, or its mask does not match the buffer shape |
Target a parameter whose consumptions are top-level arguments, or re-capture live with replayable=True |
param_value_nonfinite |
A parameter/buffer value held NaN/Inf: critical in a one-shot param_health report, and the raise-class evidence of the scheduled parameter scan, fired at the safe S-C post-mutation boundary (never mid-step()) — corrupt weights make every later step wasted compute (CheckViolationError; demotable per registration; the warn form carries the contract) |
Reload the last healthy checkpoint; forensics via tl.debug.bisect_nan on a captured trace |
params_changed_fact |
FINDING (checks kit, info, collect-only): the exact did-it-change aggregate over an accepted step (clone evidence). A corroborating fact by design: under default AdamW decay a DEAD network "changes" every step, so change is never the primary detector and no finding says "learning" | Read param_received_no_gradient for the primary zero-latency evidence |
patch_donor_pass_ambiguous |
patch_from reached a donor site that is multi-pass on the source trace while the fire context carries no pass: a donor pass is never guessed (the historical bare lookup silently returned the LAST pass's value); the teaching message names every pass-qualified donor spelling (HookValueError; experimental) |
Address one donor pass explicitly with a pass-qualified label (label:pass) |
patch_positions_invalid |
patch_from(positions=...) is not an int, a {source: target} dict or a list of integer pairs, is empty, or a SamplingPlan source was given a mapping it cannot take (InvalidArgumentError; experimental) |
Pass an int, a {source_position: target_position} dict or a list of pairs; drop the mapping for a SamplingPlan |
patch_positions_out_of_range |
A patch_from position pair or position_axis falls outside the donor or target value at fire time (HookValueError; experimental) |
Use positions inside both prompts (negatives count from the end) and the axis both values share |
patch_positions_shape_mismatch |
A patch_from donor slice does not broadcast onto the target slice (the non-position dimensions differ; a donor batch of one broadcasts) (HookValueError; experimental) |
Patch between sites with the same hidden width, and a donor batch of one or the target's batch |
patch_source_site_unresolved |
patch_from(source_site=...) names no captured op of the source trace, more than one, or a multi-pass layer by its bare label: a donor is never guessed (HookValueError; experimental) |
Pass one pass-qualified label (label:pass) or a selector narrowed to exactly one op |
patch_ineffective |
An activation-patching rerun left an empty positive fire ledger — the hook never fired, or every fire was refused (replaced=False) — so the metric row would silently equal the corrupted baseline (PatchApplicationError, RuntimeError lineage; experimental) |
Inspect tl.facets.coverage(trace), choose a facet whose home is a real computation site, or patch an explicit op site via fork.do() |
option_group_conflict |
Grouped and flat options set the same field on a merge entrypoint (ArgumentConflictError; historically ValueError) |
Use one option style |
option_group_keyword_conflict |
Flat draw kwarg and VisualizationOptions field set the same option (KeywordConflictError; historically TypeError) |
Use one option style |
option_group_type_invalid |
Grouped option has the wrong object type | Pass the documented options class |
output_attribution_failed |
A model output tensor could not be attributed to any traced op — an opaque execution boundary or a pre-bound torch function that escaped wrapping (OutputAttributionError) |
Use ordinary torch module attributes during forward, or bind/import torch functions after TorchLens has wrapped torch |
output_unsupported_tensor_variant |
A model output is a NESTED tensor constructed inside forward(), an unsupported tensor variant TorchLens cannot log (OutputAttributionError) |
Build the nested tensor outside the traced region, or pad to a dense tensor before the ops you want captured |
output_device_invalid |
Output device policy is unknown | Choose same, cpu, or cuda |
output_tree_cycle |
Model-output tree contains a self-referential container, so its occurrence-weighted tensor sum is undefined in validate_backward_pass (InvalidArgumentError) |
Remove the container reference cycle from the model output |
output_tree_depth_exceeded |
Model-output tree nesting exceeds the output-boundary depth ceiling in validate_backward_pass (InvalidArgumentError) |
Flatten the nested output containers before validating |
payload_unavailable |
The scoped non-attaching payload reader found neither a resident payload nor a lazy blob ref on the op — nothing to read (PayloadUnavailableError, ValueError lineage; experimental) |
Re-capture with save= covering the op, or save the artifact with include_outs=True |
output_not_stored |
.output read on a Recording or Trace that holds no live model output: the output is kept in memory only and is not stored with saved recordings or traces, so a loaded or unpickled object never carries it, and a fork (built from its parent's recorded values) holds none either (PayloadUnavailableError; experimental) |
Re-run the capture and read .output on the live result |
output_forward_failed |
.output read on a failed partial result (on_forward_error="return_partial"): the forward raised before the model returned (PayloadUnavailableError; experimental) |
Fix the failing forward and re-run; the partial keeps the failure |
output_capture_stopped |
.output read on a capture that stop_after= ended before the model returned (PayloadUnavailableError; experimental) |
Drop stop_after= (or move it past the last op) to let the model return |
pca_fitted_digest_mismatch |
A tl_pca_fitted_v1 sidecar's arrays hash to a different digest than the recorded one; the arrays ARE the identity (a solver seed does not reconstruct a degenerate eigenspace), so silently different numbers are refused (FittedArtifactError; experimental) |
Re-save the sidecar from the original fit, or re-fit |
pca_fitted_record_invalid |
A fitted-PCA sidecar is malformed (unreadable, wrong schema, missing arrays, non-integer counts) or save_fitted got a non-FittedPCA payload (FittedArtifactError; experimental) |
Pass a sidecar written by tl.stats.save_fitted() / a tl.stats.PCA(...).fitted(...) payload |
pca_fitted_unavailable |
PCA.fitted() was called before the estimator saw two rows; there is no covariance to solve and fabricating a basis would be a silent wrong number (FittedArtifactError; experimental) |
update() the estimator with the fitting batches first |
recipes_unknown_provider |
WARNING (not a refusal): activate_entrypoint_recipes(names=...) was asked for entry-point names that are not installed; the unknown names were skipped and the installed provider names listed |
Activate an installed provider name from installed_recipe_providers(), or install the provider distribution first |
record_generation_budget_exceeded |
tl.record(..., generate_kwargs=..., generation=GenerationOptions(max_saved_bytes=...)) would retain more payload bytes than the budget: the running total crossed it, or right after the first decode step the projection prefill_bytes + per_step_bytes * max_new_tokens exceeds it; fields["reason"] is running or projected (InvalidArgumentError; experimental) |
Declare reducers for the large sites, add keep_last= with spill=, generate fewer tokens, or raise max_saved_bytes= (None disables the guard) |
record_generation_options_invalid |
torchlens.recording.GenerationOptions was malformed (a reducer that is not a callable keyed by a site address string, a negative kv_sites layer, keep_last below 1, spill= without keep_last=, a non-positive max_saved_bytes), or tl.record(generation=...) was called without generate_kwargs= (InvalidArgumentError; experimental) |
Follow the remedy the message names; pass generate_kwargs={} for the model's default generation |
record_generation_reducer_invalid |
A per-token reducer could not run or did not meet its contract: a payload without a batch and a position axis, top_k with k < 1, probe() given something that is not a fitted linear probe or fitted on a different feature width, a reducer that raised or returned a non-tensor or a value whose first axis is not the forward's positions, a declared site a forward did not record or recorded twice, or a kv_sites layer the model's cache does not hold (InvalidArgumentError; experimental) |
Declare a site whose output is [batch, positions, ...], pass position_dim= for other layouts, fit the probe on the declared site, or name a cache layer the model has |
record_generation_step_missing |
GenerationRecording.records_at(step) or .step_of_position(position) named a step or position no recorded forward computed, or .series(name) named a series the recording does not hold (no generation=, an undeclared name, or every forward of it dropped by the ring buffer without a spill) (the last generated token is never fed back through the model; InvalidArgumentError; experimental) |
Pass a step or position inside the range the message names |
record_generation_unsupported |
tl.record(..., generate_kwargs=...) cannot hold this generation: no callable generate, an encoder-decoder model, use_cache=False or a generate that runs decode steps without a KV cache, beam search, more than one return sequence, a batch of prompts, assisted decoding, intervene=, halt= or a partial forward-error mode; fields["reason"] names which (InvalidArgumentError; experimental) |
Follow the remedy the message names (for a batch, record one prompt at a time: input_ids[i : i + 1]; without generate, tl.record(model, ids, save=...) per forward) |
record_lean_unsupported |
tl.record(..., lean=True) (experimental) was combined with gradient capture (backward_ready=True, save_grads=, default_grad=), intervene=, narrate= or a partial forward-error mode, which read the journal events of ops the selection does not keep (RecordingConfigError) |
Drop lean=True or the conflicting option |
record_not_bound |
Record's owning Trace reference is gone | Keep the owning Trace alive |
recording_events_not_retained |
to_trace() on a disk-recovered Recording |
Convert the in-session Recording |
recording_lean_omitted |
event_stream, op_events, lazy_trace, raw_metadata() or to_trace() on a lean Recording (lean=True, experimental), whose journal holds only the kept events and would answer partially; Recording.lean_omissions names what is missing (CaptureNotActiveError) |
Record again without lean=True, or read records and the other retained-record views |
recording_backward_halted |
backward() on a halted Recording (the sparse frontier retained no complete output to root the backward walk) |
Re-record without stop_after= or use trace(stop_after=...) for prefix backward |
recording_backward_inference_only |
backward() on a Recording whose forward ran under torch.no_grad() or torch.inference_mode() with no backward option, so tl.record implied inference_only=True and built no autograd graph (RecorderStateError) |
Record again with gradients enabled and pass backward_ready=True or save_grads= |
recording_backward_not_requested |
backward() on a Recording made without backward_ready=True, save_grads= or default_grad=; tl.record installed no gradient hooks, so the backward would record nothing (RecorderStateError) |
Pass backward_ready=True or save_grads= to tl.record and record again |
recording_event_stream_unavailable |
Raw per-event metadata read on a Recording that no longer holds its capture event stream — explicitly cleaned, or restored from a payload-only projection (RecorderStateError) |
Read events on the in-session Recording before cleanup |
recording_failed_not_convertible |
to_trace() on a failed partial Recording |
Fix the forward and re-record |
recording_halt_frontier_missing |
Halted Recording retained no frontier payload | Save the halt frontier or use trace(stop_after=...) |
region_edit_invalid |
do(region, edit) got no edit, or a region replacement produced a non-tensor (regions; experimental) |
Pass an edit helper, hook callable, replacement tensor, or region callable returning tensors |
region_edit_multi_exit_unsupported |
A per-value edit (helper/tensor) on a region instance with several exit ops; one evaluation per pass with atomic multi-exit commit cannot be coordinated per-value (experimental) | Pass a region callable fn(exit_values, *, ctx) returning one tensor per exit op, or tl.splice_module(module, input_route='in') |
region_effect_closure_violated |
A region member (or its buffer sink) has recorded outward-effect evidence — value-changing/unproven buffer write, collective boundary, or an in-place mutation visible outside; the replay lowering cannot honestly substitute such a region's exits (delegated check, cites the captured ledger; experimental) | Exclude the effectful op from the region, or run the edit on a live lane (intervene= / spec.bind), where changed side effects ARE the experiment |
region_empty |
region() over an empty slice: no members, no boundary (experimental) |
Check the between()/subgraph() endpoints |
region_engine_unsupported |
do(region, edit) off the replay engine; the lowering substitutes exit values without re-running the interior (experimental) |
Use engine='replay' (the default on a fork); live lanes use intervene= or spec.bind |
region_exit_address_underivable |
A region exit edge has no derivable occurrence address in the pass-exact dataflow edge family (experimental) | Re-capture with CaptureOptions(replayable=True), or reshape the region so exits are ordinary tensor arguments |
region_exit_container_unsupported |
A region exit is consumed inside a container kind the nested splice cannot rebuild (tuple/list/dict positions extend; anything else refuses rather than guessing; experimental) | Reshape the consumer to take the tensor as a plain argument, or grow the region past the consumer |
region_exits_incomplete |
A user-declared exit list LEAKS: derived exit edges are not covered; the exit set is ALL edges leaving the region, derived, never asserted (experimental) | Cover every derived exit edge, or drop exits= and let TorchLens derive the set |
region_exits_unknown |
A declared exit entry is malformed or names an edge that is not an exit of this region (experimental) | Declare (parent_label, child_label) pairs or bare parent labels from region(plane).boundary.exits |
region_not_convex |
A dataflow path leaves the region and re-enters it (between(R, R) <= R fails); no single entries-to-exits function can exist — the refusal prints one offending path (experimental) |
Grow the region to include the path, or split the edit into two regions |
region_splice_arity_mismatch |
splice_module/region-callable returned the wrong number of values for the instance's exit ops, or splice_module(input_route='in') found no entry values (experimental) |
Return exactly one tensor per exit op, in exit order |
region_target_invalid |
region() received something other than a TraceSlice (experimental) |
Build the member set with trace.between(...) or trace.subgraph(...) first |
region_trace_mismatch |
do(region, edit) on a trace other than the one the region was derived on (experimental) |
Derive the region on the trace you edit: region(fork.between(...)) |
recording_multipass_not_convertible |
to_trace() on a halted multi-pass Recording (a completed multi-pass Recording converts) |
Record one pass per Recording |
reentrant_trace |
tl.trace was started while another capture was active (ReentrantTraceError, RuntimeError lineage) |
Finish the outer capture before starting another |
release_during_active_capture |
tl.release_model() while a capture is still active |
Let the capture finish before releasing the model |
recording_option_type_invalid |
Recording option has an unsupported type | Pass the documented type for that option |
facet_snapshot_provider_missing |
Per-trace facet recipes reached the capture engine before any facet snapshot provider was registered (RegistryError; torchlens registers the provider on import, so this is internal) |
Import torchlens through its public entry before capturing with facets= |
registry_capabilities_missing |
A registration reached a typed registry door without capability rows (RegistryError; registration is refused, never accepted blind) |
Declare capabilities={...} stating what the provider can and cannot do |
registry_capability_key_invalid |
A capability row key is not a non-empty string (RegistryError) |
Use non-empty string capability names |
registry_capability_value_invalid |
A capability row value is not a portable scalar (bool/int/float/str or tuple-of-str) (RegistryError) |
Use portable scalar capability values |
registry_domain_duplicate |
A second kernel registry was created under an existing domain name (RegistryError) |
Import the owning door module instead of re-creating its registry |
registry_entry_duplicate |
A registration collides with an existing entry id; collisions refuse by default (RegistryError) |
Pass replace=True explicitly, or register under a different id |
registry_entry_id_invalid |
A registry entry id is not a non-empty string (RegistryError) |
Pass a stable non-empty string entry id |
registry_entry_unknown |
A lookup named an entry id absent from the registry; the refusal lists the registered ids (RegistryError) |
Register through the domain's public door first, or use a registered id |
registry_name_invalid |
A kernel registry was created with an invalid domain name (RegistryError) |
Pass a non-empty string registry name |
registry_provider_invalid |
A registration carries no stable provider identity (RegistryError) |
Pass provider=ProviderInfo(provider_id=...); builtins use TORCHLENS_PROVIDER |
collapse_floor_fallback |
WARNING code (TorchLensWarning): collapse="auto"/"max" fell back to the conservative floor plan; typed half on OptimizerResult (collapse) |
Reduce the rendered graph with module= focus, vis_call_depth, or rolled mode |
collapse_budget_fallback |
WARNING code (TorchLensWarning): the (U, W) work estimator refused quality-planner admission; the deterministic compact fallback plan renders instead of an uncollapsed wall (collapse) |
Reduce the rendered graph with module= focus, vis_call_depth, or rolled mode |
collapse_pathological_skip |
WARNING code (TorchLensWarning): the trace crossed the pathological pre-gate (20x COLLAPSE_OPTIMIZER_MAX_OPS raw ops) and smart collapse declined outright |
Reduce the rendered graph with module= focus, vis_call_depth, or rolled mode |
collapse_expansion_manifest |
WARNING code (TorchLensWarning): an over-ceiling overview render wrote its expansion manifest <outpath>.expansion.json |
Open a unit with module=<address> from the manifest |
collapse_watchdog_fallback |
WARNING code (TorchLensWarning): the quality planner was abandoned mid-run (watchdog/allocation cap) for the deterministic fallback; disclosed as an estimator bug with (U, W, predicted, actual) |
Report the disclosed tuple; reduce the rendered graph |
collapse_near_uncollapsed |
WARNING code (TorchLensWarning): an auto/max plan left >=90% of rendered units visible (collapse release invariant) |
Reduce the rendered graph with module= focus, vis_call_depth, or rolled mode |
layout_engine_stderr |
WARNING code (TorchLensWarning): a zero-exit Graphviz layout wrote to stderr (the cairo clamp class) |
Read trace._last_render_geometry; on a size clamp render direct SVG or reduce the graph |
render_vector_oversize |
WARNING code (TorchLensWarning): a forward SVG/PDF page exceeds the 14,400 pt per-side vector page ceiling; written as requested |
Draw with collapse='auto', focus with module=, or limit vis_call_depth |
sibling_order_fallback |
WARNING code (TorchLensWarning): the sibling-order post-pass could not lay out the ordered graph, so the render used the plain layout (invariant 11) |
Pass order_siblings=False to skip the pass |
battery_anchor_insufficient |
Threshold freezing received fewer than two anchor judgements per side (InvalidArgumentError; lens battery harness, experimental) |
Collect ten judgements per anchor before freezing |
battery_sentinel_probe_missing |
A sentinel (known-bad) packet's answer key lacks a channel-semantics probe, so the control could never fail (InvalidArgumentError; lens battery harness, experimental) |
Generate the key with generate_answer_key(..., sentinel=True) |
battery_metric_invalid |
Anchor confidence bounds overlap: the metric or the anchors are invalid; a threshold is never waived and never drifts down (InvalidArgumentError; lens battery harness) |
Fix the metric or re-anchor |
display_filter_operand_invalid |
Display-filter operand is not a closed token, token list, Selection, or predicate (InvalidArgumentError; view display filter, experimental) |
Pass a closed token, a Selection, or a callable |
display_filter_polarity_conflict |
Display filter received both include= and exclude= (or neither); v1 takes exactly one polarity (InvalidArgumentError) |
Pass exclude= |
display_filter_selection_foreign |
Display filter received a Selection bound to a different trace (InvalidArgumentError) |
Pass the unresolved selector, or align_to(this_trace) first |
display_filter_skip_fn_conflict |
display_filter and an explicit skip_fn were both passed; the filter compiles to the same hiding machinery (InvalidArgumentError) |
Pass either display_filter or skip_fn, not both |
display_filter_token_unknown |
Display-filter token outside the closed v1 vocabulary (reshapes, constants, non_module_ops) (InvalidArgumentError) |
Pass a closed token, a Selection, or a predicate |
encoding_transform_invalid |
color_by transform outside the closed vocabulary (linear, rank, log); log1p is rejected by design -- unit-dependent, measured no-op (InvalidArgumentError) |
Pass one of the closed transform tokens |
view_above_detail_budget |
An uncollapsed view (view="debug" or "dims") on a trace above the detail ceiling would render an illegible wall (InvalidArgumentError; refusal names both remedies) |
Focus the render with module= or a Selection region, or pass an explicit collapse= override |
view_attention_subject_absent |
Trace.draw(view="transformer") found zero attention structure; it never draws an ordinary graph under a domain name (InvalidArgumentError) |
Leave view= unset, or pass view='overview', for a domain-neutral picture |
view_budget_above_ceiling_fallback |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): above the optimizer ceiling no call depth lands in the visible-detail band; the nearest-depth estimate is served, disclosed as an estimate (themes N10) |
Focus the render with module= or pass an explicit depth= |
view_budget_band_missed |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): the visible-detail budget resolver found no float-schedule point inside the two-sided band; the nearest point is served with the dial disclosed by name (themes N10) |
Focus the render with module= or depth=, or pass an explicit collapse= override |
view_headline_evidence_missing |
A performance view's (speed, memory, compute) HEADLINE evidence family is absent from the capture; the picture would answer a different question (InvalidArgumentError; remedy names the capture flag) |
Re-capture with the named capture settings |
view_legend_suppression_refused |
Explicit show_legend=False on a view the legibility gate ruled legend-DEPENDENT (InvalidArgumentError; cites the gate result) |
Drop show_legend=False, or use a legend-optional view |
view_nonfinite_not_checked |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): the debug view's nonfinite channel found zero checkable payloads -- channel-level degrade: one prominent legend line, no per-node motifs (themes N6 two-mode degrade) |
Re-capture with saved payloads or CaptureOptions(on_nonfinite='track') |
view_single_pass_no_sequence |
Trace.draw(view="sequence") on a single-pass trace: nothing to sequence (InvalidArgumentError) |
Leave view= unset, or pass view='overview', for a domain-neutral picture |
view_source_family_unknown |
Performance source family outside the closed table (time, bytes, flops) (InvalidArgumentError) |
Declare one of the closed family tokens |
view_source_zero_coverage |
The view-resolved performance member has zero coverage on this capture: a populated legend over an unencoded graph is the measured ADVERTISED-SCALE defect (InvalidArgumentError) |
Re-capture with the named capture settings |
view_roll_mode_invalid |
Source-family resolution received a view outside {rolled, unrolled} (InvalidArgumentError) |
Pass the effective vis_mode |
view_member_unknown |
A view preset declared a member key that is not a draw() parameter name (InvalidArgumentError; themes registry, experimental) |
Use draw() parameter names as view member keys |
view_name_taken |
A view registration reused an existing (surface, name) key (InvalidArgumentError; experimental) |
Pick an unregistered view name or surface |
view_secondary_degraded |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): a view's SECONDARY member degraded (missing evidence or an unlicensed view); the render proceeds without it and carries the rendered notice -- silence is never an option (themes N2) |
Re-capture or adjust the view to restore the member |
view_secondary_undeclared |
A view marked SECONDARY members it does not set (InvalidArgumentError; experimental) |
Declare every SECONDARY member in the view members mapping |
view_unknown |
An internal view lookup named an unregistered row; the refusal lists the roster (InvalidArgumentError; experimental) |
Pick a registered view name |
view_user_kwarg_unknown |
View resolution received an explicit kwarg that is not a draw() parameter (InvalidArgumentError; experimental) |
Pass draw() parameter names only |
surgery_evidence_missing |
Trace.draw(view="interventions") found no intervention audit entries on the trace -- no transaction envelopes, region rows, fire records, or injected ops; with nothing recorded the picture would answer a different question (InvalidArgumentError, experimental) |
Run an edit first (fork.do(...), tl.trace(..., intervene=...), spec.bind(model), or a region do), or leave view= unset for a picture without edits |
surgery_diff_incomparable |
surgery_diff received the same trace object on both sides (a self-diff is vacuous) or an operand recording no ops (InvalidArgumentError, experimental) |
Pass the edited capture as subject and the baseline capture as reference, both finished captures |
draw_view_invalid |
Trace.draw(view=...) received a value that names no premade view; the refusal lists the allowed values (InvalidArgumentError) |
Pass one of the listed views (for example view="overview"), or leave view unset for the plain drawing |
rank_render_endpoint_undeclared |
Rank-path DOT referenced an undeclared or unpositioned edge endpoint — a guaranteed neato -n hard error, asserted at emit time instead (RankRenderEndpointError, GraphvizRenderError lineage) |
TorchLens render-pipeline bug: report the model and draw() arguments; render with layout='dot' meanwhile |
relation_assignment_type_invalid |
Finished relation field assigned a non-container | Assign list/set/tuple/frozenset or None |
report_arrays_invalid |
tl.export.html(arrays=...) received a value outside the closed "frontier" / "flagged" / "none" / Selection vocabulary (InvalidArgumentError; offline report, experimental) |
Pass one of the documented presets or a tl.Selector instance |
backward_validation_non_leaf_parameter |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): backward validation was given a model whose Parameter is already an autograd non-leaf (history from an earlier forward), so it returns False instead of comparing gradients against a stale graph |
Validate a fresh copy of the model, not the already-run one |
backward_validation_no_module_output_evidence |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): backward validation found no module-output gradient to compare (every module call is a proven exclusion, as in a model whose forward calls no child module), so it returns False as unverifiable rather than passed |
Pass validate_layer_grads=False to check parameter gradients alone |
backward_validation_carried_graph |
tl.validate(..., scope="backward") ran a backward into saved tensors an earlier backward already freed (torch's "backward through the graph a second time") on a model whose module attributes hold tensors with autograd history, for example a key table computed from an embedding at construction or a hidden state kept from the previous call; the message lists those attributes. The same torch error on a model with no such attribute propagates unchanged (ValidationError; experimental) |
Detach the carried tensors or compute them inside forward, or validate a freshly constructed model |
cka_input_nonfinite |
tl.stats.cka / tl.stats.CKA.update got NaN or infinite input, which would yield a NaN or meaningless score |
Clean or mask the non-finite entries first, as tl.repgeom.rdm requires |
cka_zero_variance |
WARNING: tl.stats.cka / tl.stats.CKA.compute returned NaN because a representation has zero variance |
Check the site selection and inputs; a constant activation carries no geometry |
stats_unit_axis_type |
tl.stats.Quantile / tl.stats.TopK got a unit_axis= that is not an integer |
Name the unit axis by position, for example unit_axis=-1 |
stats_encoder_type |
tl.stats.Quantile / tl.stats.TopK got an encoder= that is not callable |
Pass a callable such as encoder=sae.encode, or omit encoder= |
stats_unit_axis_out_of_range |
A per-unit tl.stats.Quantile / tl.stats.TopK batch has no axis unit_axis (or fewer than two axes) |
Feed batches shaped [examples, ..., units] and name an axis inside them |
stats_unit_axis_is_batch_axis |
A per-unit accumulator's unit_axis names axis 0, which is the example axis |
Name the unit axis among the other axes, for example unit_axis=-1 |
stats_unit_layout_changed |
A per-unit accumulator got a batch with a different number of axes than earlier batches | Feed batches with the same axes to one accumulator; build one per layout |
stats_unit_count_changed |
A per-unit accumulator got a batch with a different unit count than earlier batches | Feed every batch with the same unit count; build one accumulator per site |
stats_example_ids_without_unit_axis |
tl.stats.TopK().update(example_ids=...) on a pooled tracker, which keeps no ids |
Build the tracker with tl.stats.TopK(k, unit_axis=-1) |
stats_example_ids_invalid |
Per-unit tl.stats.TopK.update(example_ids=...) got ids that are not one integer per example of the batch |
Pass one integer id per example, for example example_ids=torch.arange(n) |
stats_per_unit_state_large |
WARNING: a per-unit tl.stats.Quantile / tl.stats.TopK keeps more than 256 MiB of state (units times bytes per unit); every unit is kept; once per session |
Use a smaller reservoir_size= or k=, or keep fewer units with encoder=lambda v: v.narrow(axis, 0, n) |
stats_state_unsupported |
tl.stats.save_fitted(stat, path) found an attribute value a tl_stats_state_v1 file cannot store (it keeps tensors, numbers, strings, random streams and tl.stats accumulators only); nothing is written (FittedArtifactError; experimental) |
Save a tl.stats accumulator without extra attributes set on it |
stats_state_version_unknown |
tl.stats.load_fitted got an accumulator state file whose format version this torchlens does not read (FittedArtifactError; experimental) |
Load it with the torchlens version that wrote it, or refold and re-save with tl.stats.save_fitted(stat, path) |
stats_state_digest_mismatch |
An accumulator state file's contents hash to a different digest than the recorded one, so resuming from it would fold onto unknown state (FittedArtifactError; experimental) |
Re-save the state from the original accumulator with tl.stats.save_fitted |
stats_state_invalid |
An accumulator state file has a valid digest but a state description this torchlens cannot rebuild (FittedArtifactError; experimental) |
Re-save the state with tl.stats.save_fitted(stat, path) from this torchlens |
stats_state_encoder_mismatch |
tl.stats.load_fitted got no encoder= for a state saved with one (callables are not stored), or got one for a state saved without (FittedArtifactError; experimental) |
Pass the same callable back, tl.stats.load_fitted(path, encoder=sae.encode), or drop encoder= |
stats_aggregate_cache_type |
tl.stats.aggregate got a cache= that is not True/False or a cache_dir= that is not a path or None (ArgumentTypeError; experimental) |
Spell it tl.stats.aggregate(model, data, metrics, cache=True, cache_dir='stats-cache') |
stats_aggregate_cache_unkeyable |
tl.stats.aggregate(cache=True) cannot key part of the run by value (a one-shot iterator, an opaque batch leaf, Quantile(seed=None), a model in training mode, a metric that is not a tl.stats accumulator, or an encoder=/loss_fn= whose state is not visible), so it refuses rather than risk a stale result (InvalidArgumentError; experimental) |
Follow the remedy for the named part (for example model.eval(), Quantile(seed=0), a list of batches), or drop cache= |
stats_aggregate_cache_data_unstable |
WARNING: tl.stats.aggregate(cache=True) read different batches when keying the run and when folding it, so it returned the result without caching it; once per session |
Pass a loader that yields the same batches every pass, for example DataLoader(dataset, shuffle=False), or drop cache= |
activation_reduced_to_stats |
An op's out was read on a trace captured with save="stats", which folded every out into a Spine and kept no payload (PayloadUnavailableError; experimental) |
Read the statistics with tl.stats.site_stats(trace)[label], or capture again with tl.trace(model, x, save="all") |
stats_capture_not_replayable |
Replay or validation (run, validate_forward_pass, save_new_outs, do on the replay engine) was asked of a save="stats" trace, which keeps no payloads to replay from or compare against (PayloadUnavailableError; experimental) |
Capture again with tl.trace(model, x, save="all"); tl.validate(model, x, scope="forward") runs its own full capture |
stats_capture_not_reduced |
tl.stats.site_stats(trace) got a trace not captured with save="stats" (InvalidArgumentError; experimental) |
Capture with tl.trace(model, x, save="stats"), then call tl.stats.site_stats(trace) |
stats_trajectory_data_type |
tl.mechinterp.measure_trajectory(model, data) got data that is neither a tensor nor an iterable of batches (ArgumentTypeError; experimental) |
Pass a list of batches, e.g. tl.mechinterp.measure_trajectory(model, [ids]) |
stats_trajectory_flag_type |
mask_input= or verify= on tl.mechinterp.measure_trajectory is not True/False (ArgumentTypeError; experimental) |
Pass a bool, e.g. mask_input=True |
stats_trajectory_targets_type |
A (model_input, targets) batch's targets are not an integer token-id tensor shaped [batch, positions] inside the vocabulary (ArgumentTypeError / InvalidArgumentError; experimental) |
Yield (input_ids, target_ids) with one target id per batch row and position |
stats_trajectory_statistic_unknown |
statistics= (or TrajectoryStats.compute_stats) names a statistic outside entropy, kl_to_final, max_prob, cross_entropy, target_rank, or one the result did not measure (InvalidArgumentError; experimental) |
Pass known names, e.g. statistics=['entropy', 'kl_to_final'] |
stats_trajectory_targets_missing |
cross_entropy or target_rank was requested but a batch carries no targets (InvalidArgumentError; experimental) |
Yield (input_ids, target_ids) batches, or ask for the untargeted statistics only |
stats_trajectory_layers_changed |
A later batch exposes different projected layers than the first (InvalidArgumentError; experimental) |
Pass layers= explicitly |
stats_trajectory_positions_changed |
A batch's sequence length differs from earlier batches', so per-position means cannot fold (InvalidArgumentError; experimental) |
Pad or truncate every batch to one length |
stats_trajectory_empty |
tl.mechinterp.measure_trajectory folded no examples (no batches, or no projected layers) (InvalidArgumentError; experimental) |
Pass at least one batch |
stats_trajectory_mask_input_unavailable |
tl.mechinterp.measure_trajectory(mask_input=True) got a model input that is not an integer token-id tensor (InvalidArgumentError; experimental) |
Feed token ids, or drop mask_input=True |
stats_trajectory_projection_rank |
A lens returned logits that cannot be viewed as [batch, positions, vocab] (InvalidArgumentError; experimental) |
Use a lens= returning [batch, positions, vocab] logits |
stats_trajectory_final_unavailable |
kl_to_final was requested but the trace has no readable captured output logits, or they do not cover every projected position (a logits_to_keep-sliced head) (InvalidArgumentError; experimental) |
Drop kl_to_final (statistics=['entropy', 'max_prob']), or run with full-sequence logits |
compiled_model_unsupported |
The fastlog Recorder was handed a torch.compile OptimizedModule wrapper (any options), whose compiled forward bypasses the function wrappers |
Pass the eager source module (compiled._orig_mod) or tl.trace(compiled, x); inspect the compiled code with tl.bridge.depyf.dump |
emit_nvtx_unavailable |
emit_nvtx=True on a host where torch reports no CUDA device, so no NVTX range could be emitted (torch's own emit_nvtx refuses there too) |
Drop emit_nvtx=True on this host or capture where CUDA is available |
export_expected_trace |
A graph or tracker exporter (tl.export.netron, tl.export.model_explorer, tl.export.tensorboard) was handed something that is not a Trace |
Capture first and pass the Trace, or tl.load(path) for a saved artifact |
report_graph_fallback |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): the offline report could not embed the real graph layout and fell back to the labeled schematic canvas |
Install Graphviz, or reduce the graph with vis_call_depth/module focus and re-export |
report_subject_unsupported |
Trace.explain() / Trace.to_agent_json() received a presenter (MergedTrace, TraceSlice, Bundle, Recording) rather than a Trace — a hollow report would answer the wrong question (InvalidArgumentError, ValueError lineage; experimental) |
Report on the underlying Trace (e.g. a merge member, the slice's parent trace, a bundle member, or Recording.to_trace()) |
renderer_capability_unsupported |
RenderIR requires a capability its renderer lacks (UnsupportedRendererCapabilityError, RuntimeError lineage) |
Use the graphviz renderer or drop the option needing the capability |
run_carry_state_requires_live_model |
carry_state=True on a loaded provider, which mutates staged clones and has no live model for state to carry into (experimental) |
Drop carry_state= on loaded traces, or run the live model |
run_fast_carry_state_unsupported |
carry_state=True with fast=True; fast mode's cached-oracle contract forbids declared-state mutation (experimental) |
Drop carry_state= or drop fast= |
run_fast_divergence_policy_invalid |
fast=True with a non-raise divergence policy |
Use on_divergence='raise' or drop fast= |
run_fast_until_unsupported |
until= with fast=True on a LOADED artifact, whose fast tier compiles the full recorded path; a live trace stops its native forward at the site (experimental) |
Drop until= or drop fast=, or run the live trace |
run_until_form_invalid |
until=/run-time save= run-window selection invalid: a non-string non-predicate form, an empty or unresolvable selection, sites with no producing recorded call, or a save= site outside the until= executed window (experimental; predicate/selector forms refuse separately via run_capability_unavailable at stage predicate_surface_pending until the merge) |
Pass static layer labels, module addresses, or 'saved', inside the executed window |
rerun_resave_ops_shifted |
Legacy rerun of a trace with no recorded save request (restored from pickle) whose rerun graph differs from the capture op for op, e.g. a staged edit inserted an intervention_replacement op; re-saving by the capture's raw op indices would save the wrong ops (experimental) |
Re-capture with tl.trace(model, x, save=..., intervene=...) instead of rerunning the restored trace |
run_input_missing |
Legacy rerun received no forward input | Pass the input as log.run(model, x) |
run_legacy_arguments_conflict |
trace.run(new_input, x) passed a non-module first argument and a second input |
Pass run(model, x) or run(new_input), never both forms |
run_source_model_collected |
Live model reference is no longer retained | Pass the model to trace.run(model, input) |
run_intervention_spec_not_persisted |
Legacy run(model, x) on a trace LOADED from an artifact whose persisted evidence (is_edited flags or intervention_audit rows) says its recorded values were intervened and no rerun of this session has replaced them, when the saved recipe (intervention.json) holds a callable placeholder or the artifact carries no recipe: the custom callable's code is never saved, so the rerun would execute without the recorded intervention (an edit staged after loading would run alone). The message names each placeholder's rule position and qualified name; a recipe of built-in edits only reruns. Every legacy door refuses: plain, append and chunked run(model, x), a fork's run, and do(..., intervention=InterventionOptions(engine="rerun")) (EngineDispatchError; experimental). Live traces are never refused: an empty staged spec there means it was detached on purpose |
Rebuild the placeholder rule in this session (tl.trace(model, x, intervene=...)), or re-save with built-in edits; capture plainly for the un-intervened model |
run_staged_spec_unapplied |
run_transaction(inputs=...) on a LOADED artifact (sparse or analysis provider) carrying a USER-staged intervention spec (sticky hooks staged via do()/the spec door, or staged set() value replacements): a loaded provider has no live capture to install the staged spec into, so running would silently return an un-intervened result. The live provider never fires it: run_transaction(inputs=...) on a live trace applies the staged spec inside its refresh capture and stamps the receipts on the fork's last_run (engine live, hooks, hooks_fired, hooks_unfired, unfired_plan_ids, divergence_count); a staged entry that fires nowhere follows on_zero_fire (rerun_zero_fire), and the report settles unverifiable under the hooked-run ceiling. Engine-owned sticky hooks minted by a selection do() plan are excluded — that edit was already applied to the trace's saved values, so a new-input run gets the PendingValueEditsWarning disclosure instead (never a refusal) (experimental; honesty gate). The gate does not fire for run_transaction(inputs=..., fast=True) on a live or loaded-activation trace: the guarded fast engine applies the staged spec there (glossary "Guarded fast rerun"), refusing run_capability_unavailable at stage fast_rerun_target_unsupported when the spec carries value replacements or non-module targets, and at stage fast_rerun_graph_unsteered when the recorded graph does not show exactly the staged plan (a staged entry that never fired, as after hooks staged on a plain capture, or a recorded fire no staged entry accounts for, as after clear_edits(site); the legacy door's capture engine records the current plan once) |
Apply the spec on the live trace (run_transaction(inputs=...), run_transaction(inputs=..., fast=True), or the intervened rerun run(model, x) with its guarded fast engine first and the capture fallback disclosed in last_run["fast_refused"]), or a fresh tl.trace(..., intervene=...), or detach the staged hooks (clear_edits(site) per staged site) before run_transaction(inputs=...) on the loaded artifact |
run_state_snapshot_unsupported |
The default live run() could not snapshot declared state before executing (enumeration unavailable, unprovable/overlapping alias topology, or clone/allocation failure); fail-before-execute, no forward ran (StateBindingError, ValueError lineage; experimental) |
Pass carry_state=True if you accept declared-state mutation persisting, or fix the named state entry |
run_state_restore_failed |
A declared-state restore failed AFTER execution (the live model's state is now unknown), or a later live/fast run() was attempted on a trace carrying that session-scoped state-compromised latch (StateBindingError, ValueError lineage; experimental) |
Reload known-good weights (or re-capture), then run again |
output_sink_conflict |
Disk storage and callback sink were both configured | Choose one sink |
rank_changes_by_invalid |
Bundle.rank_changes(by=) was given a value other than "site" or "module" |
Pass by="site" for one row per op or by="module" for one row per module address |
save_transformed_output_without_output_transform |
save_transformed_output=True was set with no output_transform, so there is no transformed output to save; refused when the CaptureOptions are built, before any capture |
Pass output_transform=<callable> alongside save_transformed_output=True, or drop save_transformed_output |
save_budget_invalid |
save_budget is not 'auto', a float in (0, 1], an int byte cap, or None (InvalidArgumentError, ValueError lineage) |
Pass one of the documented spellings |
save_mode_invalid |
Activation save mode is unknown | Choose a documented save mode |
state_baseline_unavailable |
An intervention-ready capture needs a byte baseline of the model's state, but pending (un-materialized) lazy parameters or buffers have no bytes at the capture boundary, so no replayable baseline can exist; refuses before any mutation with the pending slots named (CaptureNotActiveError; experimental) |
Materialize once outside capture (with torch.no_grad(): model(x)), then retry the armed capture |
save_predicate_type_invalid |
save= is neither a layer list or string, predicate, selector, nor None |
Pass a list such as save=['layer1'], a selector such as save=tl.func('relu'), or save='all' |
save_payload_level_conflict |
Optional payload family requires runnable level | Use runnable level or omit that family |
scale_requires_size_by |
size_scale= was supplied without size_by; the scale transform applies to the size channel only. UNSTABLE code (pre-ratification) |
Pass size_by= alongside size_scale=, or drop size_scale= |
selection_alignment_invalid |
Selection.align_to(target) cannot bridge this selection cross-run: exc.fields["reason"] carries the closed reason (kind_unsupported / grouping_stamp_degraded / grouping_stamp_mismatch / site_key_unavailable / site_not_in_target / index_space_mismatch) (L6 stage 4a; same-policy captures only per the L1 cross-stamp rule; experimental) |
Align live same-policy captures of one architecture; re-resolve the query Selection on the target trace otherwise |
selection_apply_invalid |
do(selection, edit) got an edit outside the closed edit surface, or an edit/selection combination the engine cannot apply (experimental) |
Pass a tl.Edit helper (zero_ablate, scale, patch_from, ...) legal for the selection's kind |
selection_bool_ambiguous |
bool() on an unresolved tl.Selector QUERY; emptiness is an element-level property of the RESOLVED selection (L6 two-level denotation; experimental) |
Call selection.resolve(trace) and test the resolved selection |
selection_kind_incompatible |
Composition or application mixes the closed selection kinds (ACT/PARAM/EDGE) (experimental) | Compose selections of one kind; resolve and apply each kind separately |
selection_trace_mismatch |
A Selection is used against a different trace than the one it was resolved on, other than a fork of that trace whose sites are unchanged (session-only binding; experimental) | Re-resolve the query Selection on the target trace |
sidecar_absent |
read_sidecar() on a trace that carries no envelope for that family (sidecar seam; experimental) |
Attach the sidecar first, or read a present family |
sidecar_budget_exceeded |
Sidecar payload is over the family's declared size budget (experimental) | Store digests/references, or register a larger size_budget_bytes |
sidecar_envelope_invalid |
Persisted sidecar envelope is not a self-describing mapping with a payload (experimental) | Re-attach through attach_sidecar(); never hand-edit envelopes |
sidecar_family_id_invalid |
Sidecar family id is not namespaced <owner_ns>.<name> (experimental) |
Use an id like myorg.saliency |
sidecar_family_namespace_reserved |
A non-TorchLens provider tried to register a sidecar family in the reserved torchlens. namespace (squat prevention for the C07X-reserved ids torchlens.input_origin / torchlens.input_digest / torchlens.boundary_facts) |
Register under your own namespace, e.g. myorg.input_origin |
sidecar_family_type_invalid |
register_sidecar_family() received something other than a SidecarFamily (experimental) |
Construct torchlens.io.SidecarFamily(...) |
sidecar_payload_invalid |
Sidecar payload is not JSON-portable (experimental) | Pass JSON-serializable payload data |
sidecar_schema_invalid |
Sidecar family declares an invalid schema id, version, or size budget (experimental) | Declare a non-empty schema_id, version >= 1, positive budget |
sidecar_trace_invalid |
Sidecar attach/read target has no annotations mapping (experimental) | Pass a captured or loaded torchlens Trace |
sidecar_version_unsupported |
Sidecar envelope declares a version newer than the registered family; the artifact is valid, the provider too old (experimental) | Upgrade the provider that owns the family |
shard_local_persistence_unsupported |
Ordinary save of a trace carrying the shard-local capture marker (distributed_scope == "rank_local_shard") while the active schema does not persist the disclosure — the PERMANENT erasure-prevention invariant at the bundle-save chokepoint: a shard-local trace must never reload as a plain trace (experimental). Trace.provenance.distributed_scope persists as of the tlspec v8 bump, so ordinary saves proceed; the refusal survives as a schema-regression tripwire |
Under a regressed schema, analyze in-session; on v8+ the save proceeds |
selection_unresolvable |
trace[selector] cannot denote the query on this trace; exc.fields["reason"] carries the closed reason (experimental) |
Branch on the structured reason: re-capture with the required evidence or narrow the query |
selection_trace_released |
Site.record read on a selection row whose trace has been released (garbage-collected or never bound), so the record cannot be reached |
Keep the trace alive while reading rows, or resolve the selector again on a live trace |
influence_geometry_unavailable |
A unit-level influence query with the geometric method met a (seed, target) pair whose receptive field has no per-unit geometry (its field status admits no per-unit answer: data-dependent, unknown or unsupported, or an ambiguous axis layout; a whole-extent sequence axis such as attention's is walked, not refused); exc.fields carries seed_site, target_site and field_status, the status that blocked it (experimental) |
Use the gradient method on a backward-ready trace for an empirical answer, or narrow the targets to sites with geometry |
influence_probe_budget |
A unit-level influence query with the gradient method would run more autograd probes (seed units times target sites) than probe_budget; refused before any probe runs, exc.fields carries probes and probe_budget (experimental) |
Narrow the seed or the targets, raise probe_budget, or use the geometric method |
selector_function_pattern_type_invalid |
func() pattern is not a string |
Pass a function-name string |
selector_subtraction_operand_invalid |
selector - other with a non-selector right operand; subtraction desugars to and(a, not(b)) over selectors only (experimental) |
Subtract a selector, or build the composition from predicate terms |
skip_fn_boundary_invalid |
skip_fn tried to skip an input or output layer |
Return False for boundary layers |
slice_save_unsupported |
trace.save() received a TraceSlice: a slice is a presenter over one trace's sub-DAG with declared dangling boundary edges, never a self-contained capture, so persisting it would imply replay/validation capabilities it cannot honour (L6 graph slice; experimental) |
Save the trace the slice was taken from (trace.save(path)) and re-derive the view after loading |
site_selector_empty |
tl.site() received neither a rendered key nor any component filter (experimental; structural selector) |
Pass op.graph.site_key, or components such as tl.site(module_path=..., func=...) |
site_selector_key_conflict |
tl.site(key) combined with component filters; the rendered key already fixes every component (experimental) |
Pass either the rendered key or components, not both |
site_selector_key_invalid |
tl.site(key) received a malformed site_key_v1 string (experimental) |
Pass a rendered op.graph.site_key string |
spec_door_extra_arguments |
An intervention door received an Recipe PLUS extra hook/edit/direction arguments; the spec already carries site, action, and direction (experimental; spec doors) |
Pass only the spec, or use the (site, hook) call shape without a spec |
spec_format_version_unsupported |
Intervention .tlspec format version is unknown |
Use a supported format version |
summary_execution_mode_invalid |
One-call tl.summary execution_mode outside 'eval'/'train'/'same' |
Use 'eval' (safe default; modes restored), 'train' (explicit opt-in), or 'same' |
spec_rule_unreplayable |
A recorded-graph door (do) received a spec containing a runtime-only predicate rule; value-dependent tests are valid only where something really runs, and no lane silently drops a rule (experimental; refused rules are named) |
Re-express the WHERE term as a structural or recorded selector, or run the spec via tl.trace(model, x, intervene=spec) |
spec_rules_duplicate |
Two Recipe clauses carry the same WHERE, action, and direction (experimental) |
Drop the duplicate clause |
spec_rules_overlap |
More than one Recipe rule matched one op at fire time; a spec never implicitly chains two edits at one site (experimental) |
Compose the actions explicitly with tl.intervention.compose(...), or narrow the WHERE terms |
summary_grad_mode_invalid |
One-call tl.summary grad_mode outside 'off'/'same' |
Use 'off' (default; forward runs under torch.no_grad()) or 'same' |
summary_level_invalid |
Summary level is unknown, or is a removed legacy preset (overview, compute, cost, graph, memory, control_flow, waterfall, output) |
Pass 'auto'/'module'/'op'; a removed preset's refusal names its replacement (view= or the public surface that serves that content) |
summary_option_conflict |
Summary axes contradict each other (level='op' with a depth= cut) |
Drop one of the contradicting axes |
summary_option_invalid |
A summary option is outside its closed vocabulary (view/style/units/buffers/columns/depth/fold_repeats/max_rows), an option name is unknown or a removed legacy spelling (preset, fields, show_ops, include_ops, mode, print_to, count_fma_as_two, show_input_preprocessing_details), or to_pandas got an unknown scope |
Pass a documented choice; the refusal names the vocabulary and the nearest match |
summary_one_call_only |
input_size/execution_mode/grad_mode passed to trace.summary(), which reports an EXISTING capture |
Use tl.summary(model, x, ...) for one-call execution options |
summary_result_legacy |
A rebuilt-result method (render('unicode'/'html'), to_markdown, to_html) called on a report with no rebuilt payload (one assembled from text by tl.report.summary) |
Call summary() (bare call, level=, view=, ...) |
summary_table_unavailable |
report.table read on a SummaryReport that is not a view="stats" report, so it carries no typed observation table |
Build the report with trace.summary(view="stats") and read .table on that report |
site_key_unavailable |
Site accessor read on a trace without site keys (legacy artifact or detached layer; experimental) | Re-capture with a current TorchLens to mint site keys |
size_by_rolled_varying |
The size_by source cannot be certified single-valued on a rolled multi-pass node (marker-varying reconciled field, unreconciled per-call/first-pass projection, or the varying output shape under "dims"); size REFUSES where color degrades — an unencoded box is indistinguishable from an encoded small box. UNSTABLE code (pre-ratification) |
Unroll the graph to size each pass by its own value, choose a cross-pass total (total_*), or pass a callable asserting your own aggregate semantics |
stack_by_auto_underivable |
stack_by=True/"auto" on a trace with no multi-pass layers, or whose multi-pass execution order is not globally monotone (chained loops, late-resumption skips, non-monotone nested tallies) — no derivable ground truth for "same column = same execution window". UNSTABLE code (pre-ratification) |
Pass an explicit annotation (stack_by=<field> or a callable) naming your own stacking semantics |
stack_by_requires_unrolled |
stack_by on a rolled graph: one aggregate node per layer leaves no per-pass nodes to stack. UNSTABLE code (pre-ratification) |
Pass rolled=False (the default), or drop stack_by |
stack_ordinals_duplicate |
Stacked ops share an execution ordinal | Narrow the selector to distinct ops |
stack_ordinals_unavailable |
Matched ops lack recorded execution ordinals | Select ops with recorded ordinals |
stack_output_not_tensor |
Stacked op's saved primary out is not one tensor | Select single-tensor-output ops |
stack_selector_no_match |
trace.stack selector matched no sites |
Pass a selector matching saved ops |
stack_shape_mismatch |
Stacked outputs have different shapes | Select ops with identical output shapes |
lightning_profile_skipped |
WARNING (not a refusal): LayerProfilerCallback could not trace the module's forward on a profiled batch (the guessed input: the batch's "x" entry, else its first element, else the batch), so that batch's record was skipped and training continued |
Pass input_getter= mapping a batch to the forward input |
lightning_summary_skipped |
WARNING (not a refusal): SummaryCallback could not run the module's forward on its sample (example_input_array or the first training batch), so the fit-start summary was skipped and training continued |
Pass input_getter= mapping a batch to the forward input, or set example_input_array on the module |
escrow_spill_detached |
WARNING (not a refusal): a deferred-selector capture kept its saved activations attached (detach_saved_activations=False), but some selected payloads were spilled to temporary disk under the escrow RAM budget and came back detached; fields["detached_spill_count"] counts them |
Save fewer sites, use a live spelling (tl.in_module(...), tl.func(...)) or backward_ready=True, or pass detach_saved_activations=True when gradients are not needed |
occlusion_selection_empty |
Scalar occlusion over a selection that resolves to zero elements, which would report a confident zero effect | Select at least one element (the op itself, or tl.units(label, [index])) |
stop_after_chunked_conflict |
stop_after= with chunk_size: the chunk fan-out runs several captures and one stop frontier is ambiguous across them |
Drop chunk_size or drop stop_after |
stop_after_never_fired |
A selector-shaped stop_after= site never fired: the capture ran the full forward, so the result is not the requested frontier |
Check the site against the model's module addresses (model.named_modules()) or use tl.func(...)/tl.module(...); exploratory predicates that may never fire belong in a callable |
stop_after_never_fired_callable |
WARNING (not a refusal): a callable or ambient stop_after site never fired; the capture ran the full forward |
Check the stop_after site against the executed model, or drop stop_after |
stop_after_site_not_live |
stop_after= received a finalized postprocess label; stop_after runs live during capture, before finalized labels exist |
Pass a module address string, a live selector (tl.func/tl.module), or a callable predicate |
on_nonfinite_invalid |
CaptureOptions(on_nonfinite=...) got a value outside the closed vocabulary; a bool or a misspelling never silently falls back to 'ignore' |
Pass on_nonfinite='ignore', 'track', 'warn' or 'raise' |
record_capture_option_unsupported |
tl.record(capture=CaptureOptions(...)) or Recorder(capture=...) set a field the recorder has no door for, or tl.record(recording=RecordingOptions(...)) set keep_op or intervene (the door's own save= and intervene=), or Recorder(recording=RecordingOptions(...)) set keep_op, intervene or postprocess, which the constructor takes as save= and intervene= and tl.record runs as its enrichment; either would be a silent no-op |
Drop the field from capture= for tl.record, or use tl.trace, which reads every CaptureOptions field; pass the predicate as save=, the intervention as intervene=, and run postprocess through tl.record or Recording.enrich |
capture_nonfinite_detected |
WARNING (disclosure warning, not a refusal): CaptureOptions(on_nonfinite='warn') found at least one op whose output carried a NaN or Inf; emitted once per capture after the forward |
Inspect the trace's nonfinite op labels (torchlens._data_classes._nonfinite.nonfinite_op_labels, surfaced by the nonfinite lens); use on_nonfinite='raise' to stop at the first one |
capture_memory_threshold_exceeded |
WARNING (disclosure warning, not a refusal): a capture kept more than 1 GiB of saved activations; emitted once per session after the forward, the capture stays complete | Keep only the ops you need with tl.trace(model, x, save=...) (a label list or a selector such as tl.in_module(...)), or save='stats' for per-op summaries; tl.errors.quiet("capture_memory_threshold_exceeded") hides the warning |
stop_after_type_invalid |
stop_after= received an unsupported type |
Pass a module address string, a tl.* selector, or a callable predicate |
structural_hash_mismatch |
Model structural hash differs from the pinned value (StructuralHashMismatchError, AssertionError lineage) |
Inspect the captured traces for the divergence, or re-pin if intentional |
plan_check_unsupported |
A plan entry the audit-only checker cannot audit without executing: a callable replacement (undeclarable output geometry) or a bare/value-dependent callable selector | Declare replacement geometry (a meta tensor or shape/dtype-bearing spec) and use structural selectors (tl.func, tl.in_module, labels) |
smoothgrad_noise_level_invalid |
smoothgrad got a zero or negative noise_level; zero noise averages identical saliency maps |
Pass a positive noise_level, or call saliency for the noise-free map |
grad_cam_layer_choice_ambiguous |
grad_cam was called without layer=; module outputs are spatial maps or token grids, but none lies on every path from the inputs to the outputs |
Name the layer, e.g. layer='<module name>'; the message lists the candidates |
grad_cam_layer_unchosen |
grad_cam was called without layer=; no module output is a spatial map or a provable token grid, or the target gradient is zero on every candidate's grid |
Name a layer whose output is N, C, H, W, or pass reshape= with it |
grad_cam_reshape_invalid |
grad_cam got a reshape= that is not callable or does not return an N, C, H, W tensor with the activation's batch size |
Return a 4D tensor, e.g. a[:, 1:].transpose(1, 2).reshape(a.shape[0], a.shape[2], H, W) |
grad_cam_token_grid_unprovable |
grad_cam got a token-sequence layer output N, T, C whose spatial grid the trace does not prove (no flattened patch grid with that token count, or several grids) |
Pass reshape=; the message spells one that runs |
attribution_input_not_float |
An input attribution method (saliency, input_x_grad, integrated_gradients, smoothgrad, gradient_shap, guided_backprop, deconvolution) got inputs with no floating-point tensor, such as token ids; integer values have no gradient |
Attribute a layer's output instead; the message spells a layer-method call on the embedding that runs |
layer_path_no_embedding |
layer_integrated_gradients or layer_conductance got integer inputs that no module turns into floats (no embedding), so the input path has no floating-point start |
Call layer_attribution, which needs no path (the message spells it), or pass floating-point inputs |
layer_path_baseline_ids_invalid |
A path layer method on integer inputs got a baseline= that does not hold integer ids of the inputs' shapes and dtypes, or whose ids do not reach the same embeddings |
Pass reference ids shaped like the inputs, e.g. baseline=torch.zeros_like(inputs), or omit baseline= for a zero embedding |
layer_path_embedding_inconsistent |
INTERNAL tripwire: an embedding module returned a different shape on a later forward pass of the integer-input route (the model's control flow changed between passes) | Report this as a bug |
grad_cam_integer_grid_invalid |
grad_cam on integer inputs found no single grid: no integer input laid out N, H, W or N, C, H, W feeds the layer, or several disagree |
Call layer_attribution for an unmapped attribution (the message spells it) |
attribution_site_not_found |
A SiteTarget names a layer that is not in dict(model.named_modules()), or its layer is not a string |
Name a module of the model; the message spells the closest name |
attribution_site_sae_invalid |
A SiteTarget sae= object lacks an encode/decode pair, or its encode returned a non-tensor |
Pass the SAE trained on the layer, e.g. SiteTarget('fc1', sae=sae, unit=0), or drop sae= |
attribution_site_unit_invalid |
A SiteTarget unit is not None, an int or a tuple of ints, or does not index the site's output shape |
Select a unit inside the output, e.g. unit=0 (the message spells it) |
attribution_site_firing_invalid |
A SiteTarget layer did not run, ran more than once without call=, has a call= beyond its calls or a negative one, or returned a non-tensor |
Name the call, e.g. call=0 (the message spells it) |
attribution_site_independent_of_input |
A SiteTarget layer's output is computed without the attributed inputs, so every attribution to it would be zero |
Choose a site the input reaches; the message spells one |
attribution_site_target_unsupported |
A method that scores only the model output (infidelity, occlusion_map) got a SiteTarget |
Use a gradient method that accepts site targets, e.g. saliency (the message spells it) |
attribution_graph_frozen_required |
tl.attribution.build_graph was called without frozen=, so it cannot know which attention patterns and normalisation scales to hold |
Pass frozen= naming those modules, or frozen=() for a model with neither |
attribution_graph_site_not_found |
A build_graph site (a transcoder's MLP, an MLP output a decoder writes, the embedding, the logits module or a frozen= entry) is not a module or op of the capture, or does not have exactly one input or output op |
Name a module from dict(model.named_modules()) that runs once, or an op label for frozen= |
attribution_graph_transcoder_invalid |
A build_graph transcoder lacks encode, W_enc, b_enc, W_dec or b_dec, has shapes that disagree, or its encode returns the wrong shape |
Pass an object with those weights in the SAE Lens orientation (the message names the one that failed) |
attribution_graph_input_unsupported |
build_graph got a capture that is not one sequence shaped (1, positions, width) with saved activations, or MLP and embedding outputs of different widths |
Capture one sequence with the default save mode, e.g. tl.trace(model, tokens[None]) |
attribution_graph_target_invalid |
build_graph got a target= that is not a non-empty list of in-range token ids, logit settings that select nothing, or a logits_at= with a unit or call |
Pass target=None, target=[token_id, ...] or logits_at=tl.attribution.SiteTarget(name) |
attribution_graph_read_site_not_upstream |
A build_graph transcoder keyed by an op label reads a value that does not run before an MLP output its decoder writes, so its features would read their own output |
Key the transcoder by an op that runs before every MLP output it writes (the message names one) |
attribution_graph_frozen_facet_unsupported |
A build_graph frozen= facet selector names a facet that is not the whole output of one op (a computed facet or a head slice), so holding its op would hold more or less than the facet |
Pass the op labels to hold instead, e.g. frozen=[str(op.label) for op in trace if op.func_name == 'softmax'] |
attribution_graph_export_argument_invalid |
AttributionGraph.to_neuronpedia got an empty slug= or model_id=, a tokenizer= without a decode method, or a node_influence_coverage= or edge_influence_coverage= outside 0 to 1 |
Pass slug="my-graph", model_id="gemma-2-2b", the model's tokenizer, and shares such as node_influence_coverage=0.8, edge_influence_coverage=0.98 |
attribution_graph_export_unsupported |
AttributionGraph.to_neuronpedia got a graph the schema cannot express: token nodes without token ids, a different number of transcoders than MLP outputs with error nodes, NaN or infinite edges or activations, no node influencing the logits, or an adjacency with a cycle |
Export a graph tl.attribution.build_graph built from integer token ids, with one transcoder per MLP it writes (the message names the remedy for each case) |
attribution_graph_contract_invalid |
tl.attribution.upload_to_neuronpedia got graph JSON that does not meet the structure of Neuronpedia's attribution-graph schema (a missing top-level key, a field of the wrong type, a repeated node id, a link to a node the export does not hold), or a dict that cannot be written as JSON; checked before any request |
Pass the dict AttributionGraph.to_neuronpedia(...) returned, or the file it wrote with path=, unchanged |
neuronpedia_upload_argument_invalid |
A Neuronpedia upload got a missing or empty api_key=, an unreadable graph file, a graph whose slug or model_id holds characters the server refuses or whose size is outside 1,024 to 104,857,600 bytes, or (Direction.upload_to_neuronpedia) an empty model_id= or name=, a negative layer=, a hook_type= other than resid_pre or resid_post, a default_steering_strength= outside -100 to 100, or a vector that is empty, non-finite or longer than 24,576; checked before any request |
Pass your own key, api_key=os.environ["NEURONPEDIA_API_KEY"], and the values the message names |
neuronpedia_upload_http_error |
Neuronpedia (or the signed upload address) answered a Neuronpedia upload with a non-2xx status, or the host could not be reached; the message names the step and the server's answer, never the key or the signature | Check the key (401, 403), the scan id and slug (400), or retry the same call (429, network) |
neuronpedia_upload_response_invalid |
Neuronpedia's answer to an upload step is not a JSON object, lacks its documented field (url, putRequestId), or gives an upload address that is not https |
Retry the same call; if it persists, the API differs from the documented one |
attribution_overlay_graph_mismatch |
trace.draw(color_by=graph) got an AttributionGraph whose sites are neither module outputs nor layer labels of the trace it is drawn on |
Draw the trace the graph was built from |
attribution_eval_map_misaligned |
deletion_curve, insertion_curve or randomization_test got an attribution that is not one tensor per evaluated input of that input's shape (a layer-space map, or a tree that does not mirror the floating-point inputs); grad_cam's N, 1, H, W maps are accepted |
Evaluate an input-space result, e.g. tl.attribution.saliency(model, x, target=0), or a grad_cam result |
attribution_audit_claim_misaligned |
causal_audit: the claim's values do not have the site's output shape on the audited inputs, the claim was computed for another target (or a layer claim has no target=), a SiteTarget target's site is not one module call; a direct-logit-attribution table whose native logits the model does not reproduce on these inputs, or one given a target=; a read table whose site shapes differ from these inputs, or whose target= is not its recorded tl.attribution.seed(...); an EDGE table audited without the corrupted_input= or metric= it was scored with, with corrupted inputs of another shape, a metric that does not return one value per example or one scalar, a target=, an example count or sender shapes from other inputs, or an edge name the component graph of these inputs does not have |
Recompute the claim on these inputs for this target, e.g. claim=tl.attribution.layer_attribution(model, x, target=0, layer='fc1'), claim=torchlens.mechinterp.direct_logit_contributions(tl.trace(model, x), answer=(1,), vs=(2,), positions=(2,)) or claim=tl.attribution.read(tl.trace(model, x), target=seed), target=seed; for an EDGE table pass corrupted_input= and metric= as given to torchlens.mechinterp.edge_scores |
attribution_audit_claim_unsupported |
causal_audit was given a claim it cannot ground: a plain tensor, an input-level result, a layer attribution at a module that does not run exactly once with one output; a direct-logit-attribution table with a component row that has no captured site (or two rows at one site), from a partial component stack, or on a model whose unembedding head does not run once; a read table with rows for several targets, or rows that are not activation_x_grad summed over a site or kept per element; a table mixing EDGE rows into ACT rows, or EDGE rows that are not one torchlens.mechinterp.edge_scores table (method eap or eap_ig, one reduction) |
Audit a layer attribution at a module that runs once, e.g. claim=tl.attribution.layer_attribution(model, x, target=0, layer='fc1'); recompute the direct-logit table with its default components; read one target with method='activation_x_grad' (claim.target('t0')); audit an EDGE table on its own, e.g. claim=torchlens.mechinterp.edge_scores(model, x, corrupted_input=corrupted_input, metric=metric), corrupted_input=corrupted_input, metric=metric |
attribution_audit_units_many |
WARNING: causal_audit is ablating (or, for an EDGE table, patching) more than 1024 units one at a time under the safe default per_unit=True |
Pass per_unit=False to measure only the top-k and control sets; for an EDGE table, or edges= naming the largest rows |
attribution_eval_setting_invalid |
An evaluation setting is invalid: num_steps not a positive int, an unknown features grouping or one the input layout does not support, a patch_size that is not positive ints, an unknown baseline, an unknown randomization, a non-callable method, an unknown similarity measure, or a causal_audit k that is not a positive int or exceeds the site's units, an unknown edit or a baseline that does not broadcast to the site, unknown controls, or num_random_draws that is not a positive int, or a road_curve ranking other than 'most_relevant_first' or 'least_relevant_first', a negative noise_std, or inputs that are not (N, C, H, W) images |
Use the spelling the message names, e.g. num_steps=20, features='elements', baseline='zeros', randomization='cascading', k=1, edit='mean' |
attribution_curve_input_unmatched |
Building a curve step's intervention spec, the one metadata trace of the model found no input layer holding an evaluated input's value, so the step cannot name its replay site | Replay the step on its perturbed inputs directly, e.g. model(step.build_inputs) |
attribution_randomization_layer_invalid |
randomization_test layers= names a module that is not in the model or has no parameters of its own, or is empty, or (with layers=None) no module with parameters ran while the method computed its map |
Name modules with parameters, top first, or leave layers=None |
attribution_randomization_maps_large |
WARNING: randomization_test is keeping more than 256 MiB of randomized maps under the safe default keep_values=True |
Pass keep_values=False to keep only the similarity measures |
attribution_randomization_map_changed |
The explanation method returned a map of a different shape after a randomization, so the maps cannot be compared | Fix the map's layout, e.g. method_kwargs={'layer': ...} for grad_cam |
structure_only_ambient_device_context |
A caller-active torch DeviceContext survives into an admitted weights-free capture and this torch build has no mode-stack primitives to absorb it (its catch-all re-entry respells every dunder op) |
Exit the construction context before capture: build the model inside with torch.device('meta'), capture OUTSIDE it |
structure_only_discharge_incomparable |
The comparable-twins preflight failed (model class, input geometry, runtime version, wrap generation, rescue asymmetry, or an opaque-witness oracle); refuse is not refute — no verdict registers | Re-capture matched twins (same class/config/versions, eval on both, both constructed before the first capture) and discharge again |
structure_only_backward_unsupported |
Backward/gradient capture is refused on a structure-only trace (v1) | Run a real capture for backward surfaces |
structure_only_discharge_precondition |
discharge_against preconditions unmet (not a structure-only trace, oracle not ordinary, or oracle not COMPLETE) |
Discharge a structure-only trace against a settled COMPLETE real capture |
structure_only_episode_unsupported |
Episode capture does not compose with structure-only (v1) | Run the episode capture without structure_only |
structure_only_measurements_unsupported |
Measurement-shaped exports (chrome_trace, speedscope, flamegraph, memory_timeline) on a structure-only capture: timings/allocator peaks are measurements a value-free capture never made | Run a real capture for measurement exports; structural tables and renders work under the hypothesis banner |
structure_only_meta_identity_unavailable |
This torch build offers no storage-identity primitive that distinguishes sibling meta allocations (data_ptr() reads 0 for every meta tensor); admission refuses rather than guessing identity |
Capture on a real device, or use a torch build with distinguishable meta storage identities |
structure_only_option_conflict |
structure_only=True combined with an option that needs tensor values (on_nonfinite='raise', replayable, a not-provably-value-free stop_after=) |
Drop the conflicting option or run a real capture |
structure_only_settlement_incoherent |
An admitted weights-free capture tried to settle with incoherent structural accounting (a value payload, a fabricated witness flag, disagreeing parameter totals, or a lost marker) — the net; a TorchLens bug, never a user error | Re-run with a real capture and report the named invariant upstream |
structure_only_substrate_mismatch |
A weights-free capture mixed meta and real substrates: at entry (mixed inputs/state, both directions, sides named) or mid-forward (a REAL tensor minted inside an admitted meta forward — stale pre-wrap factory reference, device='cpu' literal) |
Construct the WHOLE model under torch.device('meta') with meta inputs, or materialize everything on a real device; pass device= through factory kwargs |
structure_only_refuted_hypothesis |
A registered real-run discharge REFUTED this structure-only trace's hypotheses; hypothesis consumers refuse | Re-capture after fixing the divergence, or consume the discharge record directly |
structure_only_replay_unsupported |
Replay/run requires tensor values a structure-only trace never records (v1 floor; the declared late-bind posture is the row's named flip event) | Run the real model, or corroborate via Trace.discharge_against(real_trace) |
structure_only_runnable_unsupported |
Runnable save is refused on a structure-only trace (v1 floor; declared late-bind slots arrive with the L7b StateSource amendment) | Run a real capture with replayable=True for runnable artifacts |
structure_only_type_invalid |
Capture option structure_only is not a bool |
Pass structure_only=True or structure_only=False |
structure_only_validation_unsupported |
Validation entry has nothing to compare against on a structure-only trace; discharge is the verification story | Use Trace.discharge_against(real_trace) instead |
structure_only_values_unsupported |
A value-payload request (save selection, gradients, streaming sinks, raw input/output, output decode) cannot be honored under structure_only=True |
Drop the payload-requesting option or run a real capture |
sweep_intervention_conflict |
sweep() received a second intervention |
Express the target through site |
sweep_names_length_mismatch |
Sweep names and values have different lengths | Pass one name per value |
sweep_site_missing |
Sweep site target is missing | Pass site |
sweep_spec_at_conflict |
sweep(site=...) combined with InterventionSpec values; each spec already names its own WHERE and action (experimental) |
Drop at= when sweeping over specs |
sweep_spec_values_mixed |
Sweep values mixed InterventionSpec and plain replacement values (experimental) |
Pass all-spec values without at=, or all-plain values with at= |
sweep_site_type_invalid |
Sweep site target has an unsupported type | Pass a label, selector, or predicate |
sweep_values_empty |
Sweep values iterable is empty | Pass at least one value |
sweep_values_missing |
Sweep values iterable is missing | Pass a non-empty iterable |
tensor_connection_labels_missing |
Manual edge endpoint lacks a capture label | Use tensors already captured in the active trace |
text_input_exceeds_position_limit |
Text attribution without max_length got an input longer than the model config's position limit |
Pass max_length=<limit> to truncate explicitly (the span is recorded), or shorten the text |
tlspec_format_markers_incoherent |
Artifact manifest carries kind without tlspec_version yet has no spec.json — format markers are incoherent (ArtifactError) |
Restore the manifest's tlspec_version key or re-save the artifact from its source trace |
timeline_requires_trace |
torchlens._observe.memory_timeline_v2 on a sparse Recording/fastlog product with no per-op metadata rows (experimental) |
Cook with Recording.to_trace() -- a metadata-only trace suffices, activation_memory is metadata-derived |
top_n_invalid |
Requested top_n is below one |
Pass a positive integer |
trace_cleaned_up |
Public read on a Trace that cleanup() husked (TraceCleanedUpError, AttributeError lineage) |
Re-capture with tl.trace(...); cleanup permanently empties a Trace |
tracker_histogram_bucket_cap |
A histogram sketch renders more buckets than wandb's 512 cap; wandb would silently re-bin above it, measured (TrackersError; experimental) |
Watch with torchlens.trackers.WANDB_SAFE_DESCRIPTOR, or route histograms to TensorBoardSink/JSONLSink |
tracker_namespace_collision |
A foreign watcher (e.g. wandb.watch) already owns hook-installed series on this model; two watchers interleaving one dashboard refuse loudly (WatchConfigError; experimental) |
Drop the foreign watcher, or pass namespace="torchlens" to re-root every TorchLens series |
tracker_relay_histogram_unsupported |
A TensorBoard relay (wandb/ClearML) is active and histogram series ride non-uniform log2 edges the relay would silently reconstruct wrong -- measured losses (TrackersError; experimental) |
Send histograms through a native sink (WandbSink/JSONLSink) or drop histogram signals on the relay run; scalars stay faithful |
tracker_scale_invalid |
An AMP statistic correction was requested with a nonfinite/nonpositive scale, or a log2 histogram shift with a non-power-of-two scale -- rebinning is banned (TrackersError; experimental) |
Correct only GradScaler-observed power-of-two scales, or emit the record with evidence scaled_unknown_factor |
tracker_sink_capability_missing |
A requested signal needs a capability the sink does not advertise; refusing precedes any partial emission (SinkProtocolError; experimental) |
Drop the unsupported signal or use a sink that carries it (JSONLSink accepts every non-image capability) |
tracker_sink_delivery_failed |
A JSONL sink write failed and the sink latched failed; rows already written stay valid, the missing footer marks the file partial (SinkDeliveryError; experimental) |
Free disk space or point the sink at a writable path; construct a fresh sink |
tracker_sink_duplicate |
The same sink OBJECT appears more than once in watch(to=...); it would receive every point twice while its identity-keyed ledger row counted them once (SinkProtocolError; experimental) |
List each sink object once; two files need two JSONLSink objects |
tracker_sink_invalid |
The object passed as a sink implements no capabilities(), advertises unknown capability words, or is not a live vendor run object (SinkProtocolError; experimental) |
Wrap the writer in TensorBoardSink/WandbSink/JSONLSink, or implement the documented sink protocol |
tracker_sink_unavailable |
A sink or serializer needs an optional package (tensorboard / wandb / transformers / lightning) that is not installed (SinkProtocolError/WatchConfigError; experimental) |
Install the named extra, e.g. pip install "torchlens[tensorboard]" |
tracker_tag_unsafe |
A dashboard tag failed the versioned tag-safety check; TorchLens asserts and names the site, never silently rewrites -- a rewritten leaf would no longer paste back into trace[...]/named_modules() (TagGrammarError; experimental) |
Rename the offending module/parameter, or pass name=/namespace= to re-root the series |
trace_not_finished |
Export or trace.summary() requested before the forward pass finished (a partial capture has no summary; repr(trace) shows the live op count). The guard reads the trace's finished flag, which a fast-pass replay does not reset, so summary() from a hook during a fast pass is not refused and describes the prior finished pass |
Wait until trace(...) has returned |
trace_reference_collected |
Owning Trace was garbage-collected; an Op or Layer view does not keep its Trace alive, so a chained tl.trace(...)[...] read refuses |
Keep the Trace in a variable (t = tl.trace(...)) while reading its records |
trace_safetensors_invalid |
tl.io.read_safetensors read a file that is not a TorchLens safetensors Trace export (no header document, wrong schema, invalid JSON, or an unknown value tag) (experimental) |
Read files written by tl.export.safetensors(trace, path) |
trace_safetensors_trace_required |
tl.export.safetensors exports one Trace and got another object (experimental) |
Pass a Trace (export each Bundle member separately) |
trace_safetensors_version_unsupported |
tl.io.read_safetensors read an export written under a tlspec version outside this build's readable window (experimental) |
Read it with the TorchLens release that wrote it, or a newer one |
treescope_bridge_degraded |
WARNING code (TorchLensWarning, contract row in docs/reference/warning_contract.md): the installed treescope cannot render torch tensors (behavioral probe failed), so bridged object cards render without interactive array views — strict degradation, warned once per process |
Upgrade treescope to a release containing the Tensor.names fix, or view tensors natively via the TorchLens card |
treescope_bridge_unavailable |
The treescope bridge door was called without the optional treescope package installed (MissingDependencyError, experimental) |
pip install treescope |
treescope_slot_occupied |
torchlens.bridge.treescope.register() found a FOREIGN handler already holding a type's treescope registry slot; the bridge never silently replaces user display state (InvalidArgumentError, experimental) |
Unregister the existing handler first, or render through torchlens.bridge.treescope.display() without registering |
transform_axis_roles_unavailable |
A semantic role (e.g. "token") has no recorded axis-role declaration at the tensor's rank; TorchLens never guesses axis semantics from rank (transforms memo decision 11; experimental) |
Declare axis roles (e.g. TransformContext(roles=tl.transforms.BTD)) or use the explicit-axis primitive |
transform_basis_unavailable |
A digest-addressed project spec was applied but its arrays are not staged in this process; a rehydrated record carries the digest ADDRESS, never tensor values — artifact loading executes nothing (experimental) |
Rebuild the spec via project(basis, center) with the original arrays, or stage them from the fitted sidecar: pca_apply(tl.stats.load_fitted(path)) |
transform_builtin_shadowed |
A registration names a TorchLens builtin transform; builtin names are a CLOSED SET and non-replaceable (experimental) | Pick a distinct name for the custom transform |
transform_coercion_invalid |
The transform slot got an uncoercible value: not None/callable/registered name/spec/ordered sequence, an UNORDERED container (a set has no left or right), a Mapping at the single-chain door, or a non-callable at with_context (experimental) |
Pass a callable, a tl.transforms constructor result, a registered name, or an ordered list of them |
transform_extent_drift |
Flatten/features-mode SRP bound one input extent at first use for this (chain, site) and a later batch resolved a different extent; projecting different rows through DIFFERENT matrices as a function of batch composition is the measured laundering (values moved 132-153% with a batch-size change) (experimental) | Normalize the shape first (pool or pad to a fixed width), use mode='features' when only trailing extents vary, or re-extract into a fresh run |
transform_mapping_key_unknown |
A per-site transform Mapping names an output key the run does not have; a typo'd site name silently untransformed is a fails-open bug (experimental) | Key the Mapping by the run's output keys (plus tl.transforms.DEFAULT for the fallback chain) |
transform_mask_all_invalid |
Token pooling found rows with ZERO valid tokens; a token statistic over an empty set has no value, and fabricating one would be a silent wrong number (three-valued mask policy, transforms memo decision 12; experimental) | Drop or re-tokenize the all-padding rows before pooling |
transform_mask_incompatible |
A validity mask contradicts the tensor being pooled: shape not (batch, n_tokens) for the resolved token axis, or values outside {0, 1} (mask policy leg 1; experimental) |
Pass the attention mask aligned as (batch, n_tokens) with boolean or exact 0/1 values |
transform_mask_missing |
Token pooling found no validity mask anywhere and no recorded all-valid assertion; a mask-blind token statistic on a padded batch divides by the padded width and is silently wrong on real tokenizers (mask policy leg 3; experimental) | Pass the mask through TransformContext(mask=...), or assert assume_no_padding=True (recorded in the manifest as your no-padding assertion) |
transform_matrix_verification_failed |
SRP matrix re-derivation did not reproduce the recorded canonical digest (or rejection sampling failed to converge) — a construction-drift tripwire, since a cross-version construction change is an algorithm_version value, never silent (experimental) |
Report this with the recorded realized facts; it indicates a construction bug, not user error |
transform_name_not_preset |
A bare string named a registered transform that takes parameters; strings resolve only to zero-parameter deterministic presets, never a parameter mini-language (experimental) | Call the constructor instead (e.g. tl.transforms.cast(...)) |
transform_name_unknown |
A string in the transform slot names no registered transform; strings are never import paths (experimental) | Use a builtin name, register the transform, or pass the callable itself |
transform_not_differentiable |
An out/grad/activation transform returned a non-tensor, non-grad dtype, or graph-disconnected value while backward_ready=True/keep_grad=True (TrainingModeConfigError, ValueError lineage) |
Return a differentiable floating-dtype tensor that stays on the autograd graph, or declare a non-differentiable reducer with torchlens._observability.summary(fn) (the summary role reduces a detached view after the save point and is exempt by contract) |
transform_opaque_unresolvable |
An opaque transform step rehydrated from an artifact record was applied; identification is a disclosure, not code — artifact loading never imports or executes user code (experimental) | Register the transform under a versioned name and rebuild the chain from names, or pass the live callable |
transform_output_invalid |
A transform step returned a non-tensor at the engine boundary (experimental) | Return a torch.Tensor from every transform step |
transform_params_invalid |
Transform params fail their kernel's validation: non-canonical-JSON values, a non-float cast target, an op outside the closed reduce vocabulary, a literal stimulus-axis (0) address, an invalid seed/seed_source pairing, or smuggled unvalidated params on a hand-built spec (experimental) |
Fix the named parameter per the message |
transform_pipeline_record_invalid |
A persisted tl_transform_pipeline_v1 record is malformed (wrong schema id, missing steps array, non-mapping rows, unknown step kind) (experimental) |
Pass the manifest's recorded transform_pipeline block unmodified |
transform_plan_invalid |
A frozen transform step cannot plan against the concrete input: axis out of range or resolving to the stimulus axis, rank too low, or an index out of the declared bound (experimental) | Address a per-stimulus axis/index that exists at the input's rank |
transform_plan_violated |
A shard's observed post-transform output contradicts the batch-zero FROZEN plan (shape or dtype); the shard is refused BEFORE publication — ragged shape is validated per shard, never inferred forever from batch one (experimental) | Keep per-stimulus shapes fixed across batches (pad or pool before the chain), or re-extract into a fresh directory |
transform_role_declaration_invalid |
An axis-role declaration is empty or holds non-string roles (experimental) | Pass one role name per tensor axis, e.g. ('batch', 'token', 'feature_index') |
transform_role_evidence_invalid |
Axis-role evidence is outside the closed declared / op_contract / unknown vocabulary; inferred is RESERVED — rank is never evidence for axis semantics (experimental) |
Declare roles with evidence='declared' or leave roles undeclared |
transform_row_axis_violated |
A transform step changed the stimulus axis (row count/order); the stimulus axis is inviolable, enforced at the engine for built-ins AND raw callables, and the ledger row count derives from the input batch (experimental) | Reduce over non-batch axes only (e.g. tl.transforms.reduce with axis>=1), or drop the offending step |
transform_site_identity_unavailable |
srp(share='by_site') found neither a structural site key nor an output-key label to key the matrix on; silently falling back to a shared matrix would contradict the declared sharing policy (experimental) |
Run through the extraction engine (which supplies the site label), pass TransformContext(site_label=...), or declare share='by_extent' |
transform_special_tokens_unavailable |
cls_token pooling was requested without recorded special-token evidence that the tokenization actually prepends a CLS token; gathering a fictional CLS is a silent wrong number — gpt2 REFUSES (transforms memo decision 12; experimental) |
Declare TransformContext(special_tokens=SpecialTokenFacts(has_cls=True, source='tokenizer:<name>')) when the tokenizer really has one, or use pool_tokens('first'/'last'/'mean') for CLS-free models |
transform_version_mismatch |
A frozen spec's algorithm version differs from the installed registration; a version change is numerics-visible and never silently substituted (experimental) | Install the matching transform version, or rebuild the spec against the installed one |
unknown_backend |
Explicit backend name is not registered | Choose a registered backend |
unsupported_tensor_variant |
Model/input carries meta, fake, functional, or sparse tensor variants (UnsupportedTensorVariantError) |
Materialize dense, strided tensors with concrete shapes on a real device |
update_ratio_out_of_band |
FINDING (checks kit, warning): the raw Karpathy update ratio (delta-norm / param-norm at an accepted step) left the registration's explicit bounds; the lr-normalized companion rides values (no default band ships — a healthy model measured a 38x per-parameter spread; the warn form carries the contract) |
Bounds are per-registration; compare the raw and lr-normalized columns and the per-parameter history before acting |
update_ratio_zero_baseline |
FINDING (checks kit, info): an update ratio met a zero parameter-norm baseline — the ratio is inf by declaration with zero_baseline=True (never epsilon-clamped; zero baseline AND zero delta yields 0); measured as the canonical dead layer's step-0 behavior |
Expected on step 0 of zero-initialized tensors; sustained inf ratios warrant reading the change/no-gradient facts |
value_dependent_branch_unsupported |
A tensor-value escape reached user code during structure-only capture (ValueDependentBranchError; device-neutral, exact source line) |
Run a real capture, or restructure the branch to be shape-derived |
visualization_bool_option_invalid |
A bool-only draw/visualization option received a non-bool (strings such as 'no' were silently truthy) |
Pass True or False |
visualization_show_containers_invalid |
show_containers is outside its closed vocabulary, or names a removed spelling (auto, cluster) |
Pass False or one of labels, collapsed, nodes; the removed spellings are refused with their replacement named (auto drew collapsed, cluster drew labels, or nodes for the dotted tuple box) |
visualization_intervention_mode_invalid |
Intervention rendering mode is unknown | Choose node_mark or as_node |
visualization_layout_invalid |
Visualization layout is unknown | Choose auto, dot, or rank |
visualization_direction_invalid |
Render direction is unknown | Choose bottomup, topdown, leftright, or rightleft |
visualization_renderer_invalid |
Visualization renderer is unknown | Choose graphviz or a registered renderer |
visualization_theme_invalid |
Visualization theme is unknown | Choose a supported theme |
visualization_mode_invalid |
Backend visualization mode is unsupported, including module= on trace.draw(graph='backward') or graph='combined' (module focus is forward-only) |
Choose a backend-supported mode; drop module= or draw graph='forward' |
visualization_node_style_invalid |
Node style is unknown | Choose a documented style |
viz_highlighter_not_drawn |
WARNING (not a refusal): draw(show_cone=True) could not lay the downstream highlighter into the requested format (PDF or PNG without cairosvg, or another raster format); the graph is drawn without it and the edited node keeps its ring and edit row; once per call site |
Draw with file_format='svg', or install cairosvg for PDF and PNG |
watch_budget_exceeded |
A hard preflight cap (sites/bytes/elements per step) is exceeded by the resolved plan FACTS; nothing was emitted and no loop time was spent (WatchConfigError; experimental) |
Narrow select=, reduce requested signals, or raise the budget deliberately |
watch_budget_invalid |
An unknown budget key was passed; the budget vocabulary is closed (WatchConfigError; experimental) |
Use max_sites, max_bytes_per_step, or max_elements_per_step |
watch_check_outcome_invalid |
A check outcome outside the closed 0/1/2 (pass/warn/fail) vocabulary; dashboards threshold on these exact values (WatchRuntimeError; experimental) |
Pass 0, 1, or 2 |
watch_close_empty |
A watch closed with ZERO successfully emitted data points for its requested signals -- the empty-panel-with-no-explanation failure class (WatchRuntimeError; never raised while a user exception is unwinding; experimental) |
Read the close report's sink rows and named skips |
watch_lifecycle_invalid |
Collector lifecycle misuse: plan/attach before discover, or double attach (WatchLifecycleError) |
Follow discover -> attach -> step -> detach |
watch_phase_missing |
A step scope closed without the optimizer boundary its requested signals need; the series would be silently absent (WatchRuntimeError; experimental) |
Step the optimizer inside the scope, or pass allow_missing_phases=True for mixed train/eval loops (recorded as a named skip) |
watch_plan_empty |
The watch site selection matched nothing; zero-match selectors refuse at plan time (WatchPlanError) |
Pass sites= matching module paths or parameter names, or sites=None for leaf modules |
watch_plan_invalid |
Un-collectable watch request: a stream outside Route A, an unknown cadence stream, or param streams without the optimizer boundary (WatchPlanError) |
Use Route-A streams and pass attach(optimizer=...) for parameter streams |
watch_facet_shape_invalid |
A facet splitter's declared axis does not carry the declared slice count; a mis-split axis would relabel every facet series (WatchRenderError) |
Pass the correct dim=/count for the layout |
watch_quantile_invalid |
Derived-quantile request outside [0, 1] (WatchRenderError) |
Pass q in [0, 1] |
watch_population_empty |
Derived quantile over a sketch with no finite elements; a quantile of nothing would invent a number (WatchRenderError) |
Check presence/nonfinite disclosures before deriving quantiles |
watch_payload_not_observed |
Sink payload conversion on a non-observed observation; missing never renders as zero (WatchRenderError) |
Convert only presence='observed' observations |
watch_sketch_missing |
Histogram payload requested from a spine-only observation (sketch cadence tier) (WatchRenderError) |
Lower the sketch cadence for the stream, or emit the scalar spine payload |
watch_site_unknown |
Renderer/series read for a site_id absent from the run catalog (WatchRenderError) |
Use a site_id from view.sites |
watch_phase_ambiguous |
A series read spanning multiple phases with no phase named; merged phase axes mix pre/post-clip or scaled/unscaled numbers (WatchRenderError) |
Pass phase= explicitly |
watch_series_empty |
Renderer/series read matched no observations (WatchRenderError) |
Check the plan table: was the series scheduled? |
watch_tabular_extra_missing |
to_pandas() without pandas installed (WatchRenderError) |
Install pandas |
watch_page_out_of_range |
Contact-sheet page beyond the deterministic page count (WatchRenderError) |
Pass a page in [0, pages-1]; pagination is full and numbered, never truncated |
watch_selector_matched_no_sites |
The tier-P selection matched no parameters on the model (WatchConfigError; experimental) |
Pass select= entries prefix-matching named_parameters() keys, or select=None for every parameter |
watch_signals_invalid |
An unknown/empty signal request, activations without a selector (there is NO default activation selector), or activations without inputs= (WatchConfigError; experimental) |
Request a nonempty subset of the closed signal vocabulary with the named companions |
watch_sparse_grad_unsupported |
Gradient watching was requested over parameters of modules constructed with sparse=True; the gradient reduction needs dense grads and would crash inside optimizer.step(), aborting the update (WatchConfigError; experimental) |
Exclude those parameters via select=, or construct the module with sparse=False |
watch_step_conflict |
A step transaction is already open; steps never nest (WatchLifecycleError/WatchRuntimeError) |
Close the open step before starting the next |
watch_step_invalid |
A negative global step; the step axis is the caller's nonnegative training coordinate (WatchRuntimeError; experimental) |
Pass the loop's real nonnegative global step |
watch_step_source_missing |
An optimizer step ran with no step source; there is no hidden step counter, ever (WatchRuntimeError; experimental) |
Wrap the step in with watch.step(n):, pass step=<callable> at watch(), or drive from a framework callback |
watch_tier_unavailable |
A deferred watch tier was requested: activation gradients (the backward-observer seam) (WatchConfigError; experimental) |
Drop activation_grads, or capture a step with backward_ready=True and read gradients from the trace |
watch_env_config_invalid |
A TORCHLENS_WATCH_* configuration variable read by an explicit watch callback is set but malformed (not a positive integer, not none where allowed, an empty list, or a signal outside the closed vocabulary) (WatchConfigError; experimental) |
Fix the named variable or unset it; constructor arguments win over the environment |
watch_op_grain_cost_disclosed |
WARNING (not a refusal): an op-grain watch attached with the consented root-forward wrap; the attach-time calibration's median ratio of a sampled step's forward against the plain forward is disclosed | Raise every= to sample fewer steps, or narrow select=; session.plan_report() has the full calibration |
watch_forward_wrap_consent_required |
watch(grain="op") without allow_forward_wrap=True: op-grain watching wraps the root module's forward so sampled steps run inside one fastlog capture, and that cost needs explicit consent (WatchConfigError; experimental) |
Pass allow_forward_wrap=True (attach then calibrates and discloses the cost), or watch at module grain |
watch_grain_invalid |
watch(grain=...) outside the closed set: None (module grain) or "op" (WatchConfigError; experimental) |
Omit grain= or pass grain="op" |
wrappers_removed_before_capture |
A concurrent unwrap_torch() removed the torch wrappers between model preparation and capture admission |
Do not call unwrap_torch() concurrently with capture entry; re-run tl.trace to re-install the wrappers |
xarray_presentation_mismatch |
tl.export.xarray met saved activations that disagree on the leading (presentation) size |
Save only sites that share the presentation axis, or export one site with tl.bridge.xarray.data_array |
validation_model_copy_failed |
WARNING (not a refusal): forward validation could not deep-copy the model and fell back to the live model; the message names the exception the copy raised; a following precondition refusal names the same error and records this code in the failure's extra |
Free device memory or validate on the host (tl.validate(model.to('cpu'), inputs, scope='forward')); otherwise make copy.deepcopy(model) succeed |
Constant-spelled refusal kinds¶
These refusals identify themselves on exc.fields["kind"] (one
entry per structured finding) rather than exc.fields["code"], and their identifier
strings are spelled as module-level constants rather than inline code="..."
literals. They are part of the same stable public vocabulary: branch on the kind
string, never on message text. The lockstep gate enrolls each constant explicitly
(scripts/checks/error_contract_lockstep.py), so renaming the constant or drifting its
string value fails the gate exactly like an inline code.
| Kind | Refusal | Remedy class |
|---|---|---|
ambiguous_group_lifetime |
A collective used a process group whose pre-arming lifetime cannot be proven | Call tl.distributed.arm() at process start, before any group is created |
uncaptured_collective_op |
Arm-time recognizer set-inequality or dispatcher schema scan found a collective the wraps would not capture | Upgrade TorchLens to a build whose recognizer covers the installed torch, or avoid the unrecognized collective in the traced forward |
weightsfree_facade_input_evidence_required |
summary() on a meta-built model with no input evidence: the zero-argument inference rung runs real probing forwards a weights-free model cannot serve | Pass input_shape= (declared shapes) or explicit meta inputs (torch.zeros(..., device='meta')) |
wildcard_recv_unsupported |
A point-to-point receive from ANY_SOURCE cannot be attributed to a sender |
Pass an explicit source rank to recv/irecv |
intervention_fire_results_unrecordable |
An intervention changed execution but its tensor accepts neither transient metadata nor a weakly referenced out-of-band fire-result record | Intervene on ordinary tensor outputs, or drop the intervention for this op |
intervention_fire_results_cleanup_failed |
Intervention fire metadata could not be cleared after consumption; refusing prevents stale evidence entering a later capture | Re-run the capture; report the tensor type if it recurs |
root_entry_point_unavailable |
The rerun/append identity gate is fail-closed on the root entry-point fact (Trace.provenance.root_entry_point, written unconditionally on every capture) and this trace carries none -- a legacy artifact the gate cannot prove anything about |
Re-capture with a current TorchLens, or use the replay engine (re-executes recorded ops, no live model) |
rerun_entry_point_unsupported |
rerun/append cannot re-execute this capture's entry point: a bound_method root (interim posture -- supplying the owner would run forward/__call__, a DIFFERENT entry point, under a report that could claim fidelity) or any other non-module_call root refuses at the identity gate |
Use the replay engine, or re-capture from the plain module root (tl.trace(model, ...)) if module-forward rerun is wanted |
rerun_selector_unmatchable_live |
A rerun's staged edit fired at none of the sites its selector matches: either a plain rerun replayed the same graph on the same inputs and the selector matches at least one site on the trace, or (on any inputs, append reruns included) the selector is a tl.where predicate that matches at least one site on the rerun's own finished trace (for example tl.where(lambda p: p.layer_label == ...): layer_label exists only after postprocess, so a live forward never matches it). Refused instead of returning an un-edited trace; the trace is unchanged. Only a predicate that matches nothing on the new inputs completes and warns rerun_zero_fire (LiveModeLabelError; experimental) |
Stage the edit with a selector a live forward can match (tl.module(...), tl.func(...), tl.head(i, facet).in_module(...)), or propagate it on the captured input with the replay engine (do(..., intervention=InterventionOptions(engine="replay"))) |
rerun_predicate_restage_mismatch |
A rerun (plain, append, or chunked) re-armed the trace's retained capture-time intervene= predicate to reproduce its per-op staged entries, and the predicate fired at a different set of ops than the staged entries name (the input changed what it matches, or some entries were detached); the rerun is refused and the trace is unchanged (ControlFlowDivergenceError; experimental) |
Capture fresh with tl.trace(model, x, intervene=...) for this input, or re-stage the edit with a module or function selector through do |
rerun_zero_fire |
A rerun hook plan entry fired at zero sites on the new inputs. Under the default on_zero_fire='warn' it is a WARNING: the rerun completed but those interventions were no-ops. Under Trace.run(..., on_zero_fire='error') it is a SiteResolutionError refusal (the capture engine refuses before the swap, so the trace is unchanged; the fast engine refuses after recording the run on last_run) |
Resolve the target sites against the rerun trace (trace.resolve_sites) before re-applying, or route the edit through the replay engine (fork().do(...)), which validates sites at plan time |
foreign_kernel_boundary |
WARNING (not a refusal; contract row in docs/reference/warning_contract.md): a custom autograd.Function forward left torch (a numpy or dlpack export or re-entry inside apply, or a known foreign kernel such as FlashAttention 4's flash_attn.cute Functions), so the whole Function was captured as one autogradfunction boundary op whose interior is not logged and which replays through the Function's apply; fires once per Function class per capture |
Select the op with tl.func_transform("autograd.Function"); keep the Function's forward in torch if its interior must be visible |
torchscript_boundary |
WARNING (not a refusal; contract row in docs/reference/warning_contract.md): a torch.jit.ScriptFunction called from an eager forward was captured as one jitscript boundary op whose interior is not logged and which replays by calling the scripted function again; fires once per scripted function per capture |
Select the op with tl.func_transform("jit.script"); set PYTORCH_JIT=0 before the model's code is imported to capture its interior |
legacy_constructor_uncaptured |
WARNING (not a refusal): wrap_torch left a legacy tensor constructor (torch.<dtype>Tensor, Variable) unpatched because another tool's Python-level __new__ is in effect on it (or one was set and removed and its C constructor cannot be recovered); calls to it during capture are not logged |
Remove the other tool's __new__ patch before the first capture (in a fresh process if it was already applied and removed) |
runnable_random_init_run |
WARNING (not a refusal): a weight-free runnable artifact is executing on RANDOM role-init state -- outputs come from a freshly initialized model, not the captured one | Re-save with trace.save(path, level='runnable', include_weights=True), or bind real weights with trace.load_state_dict(state_dict) before run() |
patch_campaign_all_identical |
WARNING (not a refusal): an activation-patching campaign's every fire replaced the site value with an identical tensor, so the table is guaranteed to equal the corrupted baseline | Inspect tl.facets.coverage(trace) and re-anchor the facet before publishing the table as a null result |
extraction_position_ids_derived |
WARNING (not a refusal): extract_dataset derived position_ids from a non-right-aligned attention mask and passed them to the model's forward (disclosed once per run; exact for absolute-position models, a no-op for rotary models) |
Right-pad the batch or pass explicit position_ids to silence the derivation |
annotation_sweep_sites_skipped |
WARNING (not a refusal): a default *_evolution sweep skipped saved sites that are not stimulus-indexed (buffer overwrites, leading-axis mismatches) instead of fabricating stimulus-space results from them |
Select stimulus-indexed sites explicitly; an explicit save= selection of a skipped site raises the full teaching refusal |
echo_argument_invalid |
narrate= (or NarrationOptions.sites/NarrationOptions.stats) received an unsupported spelling -- strings other than 'modules', lists, non-callable objects, or an unknown stats rung; label/substring selections resolve against final labels that do not exist during a live forward |
Pass True, 'modules', a live selector/callable, or tl.options.NarrationOptions; use trace.narrate(select=...) post-hoc for final-label selections |
echo_selector_not_live |
An narrate= selector needs finalized graph facts (output/identity kinds) that do not exist during a live forward; TorchLens will not silently run a second pass and narrate the replay as though it were live |
Narrate post-hoc via trace.narrate(select=...), or scope live echo with tl.func/tl.in_module |
echo_as_save_predicate |
An NarrationOptions was routed into save=: the save slot is evaluated twice per declined op (the measured 554-evaluations-for-277-events alias retry) and a narrator that saves nothing declines everything |
Pass it via narrate=; keep save= for retention (the two scopes are independent) |
echo_via_hooks_unsupported |
An NarrationOptions was routed into hooks=: narration through the intervention runtime pays content probes and provenance records (+101% measured trace cost) and cannot render module path, depth, or pass |
Pass it via narrate= -- the read-only observer slot is the one narration mechanism |
echo_backend_unsupported |
narrate= live narration is torch-only in this release; a preview backend swallowing it would read as "nothing matched" |
Capture on the torch backend, or narrate post-hoc via trace.narrate() |
echo_cache_unsupported |
narrate= cannot combine with cache=True: a cache hit replays a stored product and runs no forward, so there is nothing live to narrate |
Drop cache=True, or narrate the cached trace post-hoc via trace.narrate() |
echo_chunked_unsupported |
narrate= cannot combine with chunked forwards (chunk_size=): the chunk fan-out runs several forwards into one Trace and per-chunk narration interleaves |
Trace chunks individually with narrate=, or narrate the assembled trace post-hoc |
echo_stats_requires_values |
An echo stats rung was armed on a structure_only=True capture, which retains no tensor values (every value-bearing claim is a hypothesis) |
Use stats='off' metadata narration, or drop structure_only |
echo_stats_numel_budget |
The live stats='exact' rung refused a tensor above the documented per-line numel budget instead of stalling the forward for a whole-tensor scan |
Use stats='is_sampled' (bounded budget, no finiteness claim), or compute exact stats post-hoc via narrate() |
echo_zero_match |
WARNING (not a refusal): a scoped narrate= capture completed with zero narrated events -- the selector matched nothing |
Check the selector against trace labels, or use narrate=True |
echo_sink_disabled |
WARNING (not a refusal): echo narration was disabled after an observer/sink instrumentation failure; capture continued unaffected and the original exception (if any) always wins | Fix the sink or selector and re-run |
clean_step_repeats_invalid |
tl.report.measure_clean_step was given repeats < 1 or warmup < 0 |
Pass warmup >= 0 and repeats >= 1 |
cost_report_tier_unknown |
tl.report.overhead(tiers=...) named a tier outside the measurable set, or omitted the required raw_forward baseline |
Pass tiers from COST_REPORT_TIERS; each maps to one public callable and ratios derive against raw_forward |
cost_tree_top_k_invalid |
tl.report.cost_tree(k=...) was not a positive integer or None |
Pass k >= 1 to keep the k largest rows per parent, or None for all rows |
device_peaks_row_invalid |
A tl.report.device_peaks row was not a PeakRow or lacked its source citation/date |
Construct PeakRow(...) with full provenance (citation, date, clock assumptions) per row |
device_peaks_unknown_device |
A peaks lookup named a (device, execution mode) pair with no catalog row | Add an explicit PeakRow with the vendor's ADVERTISED dense per-mode peak; nothing is ever auto-selected |
instrumented_rate_cuda_unsupported |
Every timed op in the trace executed on CUDA: host-side instrumented time is not a CUDA rate in either direction | Use Nsight/NVTX visual correlation (docs/reference/device_attribution.md); a joined per-kernel table is a later release |
kernel_utilization_requires_device_join |
attributed_kernel_utilization needs joined per-kernel device time, which requires the correlation-ID Kineto join |
Use NVTX/Nsight visual correlation today; for a publishable figure use tl.report.mfu with a measured step time |
machine_balance_basis_invalid |
The internal roofline helper torchlens.report._cost_perf.machine_balance was given an unknown ceiling basis or a non-positive ceiling |
Pass basis="measured_achievable" or "advertised" with positive compute/memory ceilings; the basis is disclosed on every render |
mfu_denominator_invalid |
tl.report.mfu was fed a denominator other than uninstrumented end-to-end step wall time |
Pass step wall time (tl.report.measure_clean_step is the opt-in helper); the kernel-union quantity is attributed_kernel_utilization, never MFU |
mfu_mode_peak_missing |
An execution mode carried model FLOPs but no positive advertised peak | Supply an advertised dense peak per execution mode (tl.report.device_peaks), or drop the unknown mode explicitly |
mfu_exceeds_one |
WARNING (not a refusal): tl.report.mfu computed a utilization above 1.0 -- a mode/peak/scope/timing input is wrong |
Verify each execution mode's advertised peak matches its real execution path and that step_seconds covers the whole step |
mfu_peaks_source_invalid |
tl.report.mfu(provenance=MfuProvenance(peaks_source=...)) was outside the closed provenance vocabulary |
Record where the peaks came from: user_supplied or catalog |
mfu_step_seconds_invalid |
tl.report.mfu(step_seconds=...) was not positive |
Pass the measured end-to-end step wall time in seconds |
cost_tree_depth_invalid |
tl.report.cost_tree(max_depth=...) was not a non-negative integer or None |
Pass max_depth >= 0 (0 keeps only the root), or None for the full tree |
padding_waste_length_invalid |
tl.report.padding_waste(padded_length=...) was not a positive integer |
Pass the padded sequence length S of the captured batch |
padding_waste_lengths_invalid |
tl.report.padding_waste(real_lengths=...) was empty or held a value outside [0, padded_length] |
Pass one real token count per batch row, each <= padded_length |
flops_report_inputs_required |
The tl.report.flops model door was called without example inputs |
Call tl.report.flops(model, example_inputs) |
flops_report_trace_door_inputs |
The tl.report.flops trace door was passed model-door inputs |
Call flops(trace) with no inputs, or pass the model itself to run the one-capture model door |
partial_trace_member_unavailable |
A report-family member (summary/profile/to_pandas/to_agent_json/output_table) was called on a PartialTrace, whose failed capture never reached label/identity finalization |
Use partial.explain() for the failure diagnosis or partial.audit() for the degraded findings; partial.raw_layers holds the committed per-op records |
surface_registry_unknown |
A report-family registry lookup named a surface outside the registry | Use one of the registered surface keys (the message lists the roster) |
onebackward_torch_unsupported |
The running torch lacks the GradientEdge / Node-prehook surface the one-backward read engine seeds and freezes through | Upgrade torch to a version providing torch.autograd.graph.GradientEdge (2.4+), or pass frozen=None where only the freeze mechanism is missing |
read_addressing_unavailable |
A one-backward read needs a live autograd registry and this trace cannot serve one; fields["reason"] is closed: cleaned / inference_only / chunked_forward / structure_only / is_detached / not_live / backend_unsupported / graph_freed |
Re-capture live in this process (matching the named reason's recipe) and read before cleanup or any graph-freeing backward |
read_site_unaddressable |
A named read site has no usable autograd (node, slot) (graph inputs and non-differentiable outputs have no producer node) |
Pick a differentiable op site from the trace |
read_target_invalid |
A read target request is unparseable, ambiguous, out of range, detached from the autograd graph, non-scalar, complex, or non-finite; teaching messages name the edge-seeded spelling and the site's recorded shape | Use seed(site, index=...) / seed(site, cotangent=...) (needs no payload), or a graph-connected scalar Tensor / Trace -> Tensor callable under backward_ready=True |
read_option_invalid |
A read option is outside its closed vocabulary (method, reduce, target_batch_size, within kind) or meaningless for the method (target=/frozen= with method='activation') |
Pick a value from the closed vocabulary the message lists |
read_payload_unretained |
An explicit within= names sites without retained payloads under an activation-bearing method (explicit enumeration is a contract) |
Re-capture with save= covering the named sites, or use method='grad' (no payload needed) |
read_payload_untrustworthy |
save_mode='view' payloads cannot be proven unmutated, so activation-bearing methods refuse fail-closed |
Re-capture with save_mode='copy', or use method='grad' |
read_population_invalid |
An explicit within= names sites absent from this trace |
Pick pass-qualified op labels from the trace |
read_result_budget_required |
reduce=None with multiple targets retains dense values; the read refuses without (or over) an explicit result-byte budget, naming the estimate |
Pass result_byte_budget=, narrow within=, or use a named scalar reduction |
read_frozen_selection_invalid |
An explicit frozen= operand is not an ACT selection of usable op sites |
Freeze differentiable activation sites |
read_frozen_policy_invalid |
A frozen-policy registry name is unknown or already registered | Pick a registered policy (v1: mlp_out) or pass an explicit frozen= Selection |
read_frozen_choice_required |
(Branch R of the disclosure, default-off) frozen= was omitted on an attention-bearing model under a gradient-bearing method; nothing was computed until the user chooses |
Pass frozen=None (total derivative) or an explicit frozen= Selection |
default_frozen_sites_underivable |
The default linearization needs semantically resolvable transformer MLP-output facet homes and this attention-bearing capture has none (the resolver never guesses from names) | Pass an explicit frozen= Selection of stop sites, or frozen=None for the total derivative |
batched_attribution_unsupported |
A batched VJP chunk hit an operator without a batching rule; never a silent sequential fallback | Pass target_batch_size=1 to run sequentially |
read_row_vocabulary_invalid |
A ReadRow was constructed outside its closed kind/status/resolution/grain vocabularies |
Construct rows through the read engine |
read_table_key_ambiguous |
A bare label lookup matched rows across several targets | Index with the full (target_id, kind, address) key or narrow with target |
read_table_target_unknown |
target named a target id the table does not carry |
Pick an id from target_ids() |
read_table_column_unknown |
column() named a field ReadRow does not have |
Pick a listed ReadRow field |
read_table_grain_unaggregatable |
aggregate_targets folds site-grain scalar scores and the table carries element-grain rows |
Re-read with a named scalar reduction before aggregating |
read_table_values_mode_invalid |
to_pandas got a values mode outside ('omit', 'object', 'explode') |
Pick a supported mode |
read_table_not_portable |
The v1 read-table artifact is scalar-only and this table carries dense element-grain values | Save a scalar table (named reduction) or keep element-grain tables in session |
read_table_artifact_invalid |
A persisted read-table artifact is unreadable, over the bounded-reader ceilings, or violates the closed row schema (fail-closed load) | Re-save the table with ReadTable.save on this TorchLens version |
read_alias_conflict |
Members of one (node, slot) alias group disagreed on their shared gradient factor -- an engine defect, not a user error |
Report this as a bug |
by_score_invalid |
A by= ReadTable cannot rank this request; fields["reason"] is closed: by_table_foreign / by_table_stale / by_table_multi_target / by_table_kind / by_table_empty / by_table_grain_mixed / by_table_index_space_mismatch |
Re-run the read against this trace, narrow with target, or fold with aggregate_targets |
population_not_covered |
An explicit by= ranking population names sites the ReadTable cannot rank (missing, non-ok, or unrankable rows); explicit enumeration is a contract |
Re-read with a population covering the named sites, or drop them from within= |
read_edge_provenance_unavailable |
The grad-input correspondence map needs edge-use provenance this trace did not record | Capture with CaptureOptions(replayable=True) |
read_pass_origin_invalid |
A backward-pass origin stamp is outside ('internal', 'read', 'user') or re-stamps an already-stamped pass |
Stamp each recorded pass exactly once with a listed origin |
read_suppression_leak |
INTERNAL tripwire: a suppressed read leaked pinned autograd refs (a TorchLens contract breach, never a user error) | Report this as a bug; re-capture before further reads |
read_engine_call_drift |
INTERNAL tripwire: the engine's exact autograd call count drifted from its plan | Report this as a bug |
postprocess_step_postcondition |
INTERNAL tripwire (MetadataInvariantError): a postprocess step (1, 8, 11, 15.5, 16, 16.5 or 17) left its postcondition unmet; the message names the step. A TorchLens defect, never a user error |
Report this as a bug |
aten_values_consistent |
INTERNAL tripwire (MetadataInvariantError): a kept AtenOp.out disagrees with its output facts or with its owning Op's saved output, or was kept for a call that raised or whose Op saved nothing; the message names the row. A TorchLens defect, never a user error |
Report this as a bug |
read_frozen_default_linearization |
WARNING (not a refusal): frozen= was omitted on an attention-bearing model, so the default MLP-output linearization deliberately changes transformer saliency numbers relative to Captum-family tools; emitted once per process |
Pass frozen= explicitly (None = total derivative; omitted/DEFAULT = published direct-edge linearization) |
attribution_method_binding_invalid |
Wrapper route violation: neither/both of attribute=/method=, method_kwargs without method=, sugar route without model/target, or a non-Attribution return |
Pass exactly one route: a closed attribute=(inputs, input_kwargs) callable, or method= with model=, target=, and an explicit method_kwargs mapping |
attribution_target_invalid |
Int attribution target against a non-tensor model output | Use a callable target built from the model output |
attribution_target_not_differentiable |
Attribution target scalar is not differentiable with respect to the attributed inputs | Choose a target built from the model output |
gradient_shap_draw_bank_invalid |
Stored-draw bank geometry does not match (samples, batch, pool) or values are out of range | Replay a bank stored by store_draws=True |
gradient_shap_pool_invalid |
GradientShap baseline pool missing, misaligned with the input leaves, or with inconsistent pool sizes across leaves | Stack input-shaped baseline examples on ONE leading pool axis, mirroring the input structure |
guided_forward_fidelity_violated |
The exact-ReLU rewrite did not reproduce the plain forward bit-exactly (a forward discards an in-place ReLU return value) | Use the returned tensor of in-place ReLU calls in the model's forward |
guided_no_relu_sites |
Guided backprop/deconvolution matched ZERO exact-ReLU sites; the refusal names the observed activation kinds | Use these methods on ReLU models; for other activations use saliency, input_x_grad, or integrated_gradients |
guided_sites_invalid |
sites= outside the closed ('all', 'module') vocabulary |
Use 'all' for op-level coverage or 'module' for nn.ReLU-dispatched firings |
layer_conductance_edge_missing |
INTERNAL tripwire: a conductance path run requested right-edge activations but returned none (a TorchLens contract breach, never a user error) | Report this as a bug |
layer_path_gradient_missing |
INTERNAL tripwire: a require-gradient layer-path capture returned no gradients (a TorchLens contract breach, never a user error) | Report this as a bug |
lrp_stash_unpaired |
SiteStash.fetch found no stashed fact for this site/name (unpaired backward firing or never-stashed fact) |
Stash the fact in the site's forward hook, once per firing |
metric_attribution_shape_mismatch |
Infidelity received layer-space or CAM-shaped values that do not mirror the attributed input leaves | Evaluate an input-space method, or expand the layer attribution into input space first |
metric_determinism_probe_failed |
Sensitivity's behavioral probe: two calls on the UNPERTURBED inputs differ beyond the 1e-6 relative tolerance | Seed the wrapped method's randomness, or pass a stored sample bank |
metric_determinism_unfrozen |
Sensitivity over a known-stochastic method without a seed or stored bank (estimator noise would masquerade as input sensitivity) | Fix the method's seed or pass a stored sample bank |
metric_perturbation_invalid |
Metric perturbation policy violation: unknown policy token, non-spatial square-removal input, invalid sample counts/radius, or a callable escape breaking its contract | Choose a documented policy or satisfy the (perturbations, perturbed_inputs) callable contract |
metric_perturbation_out_of_range |
WARNING: an infidelity perturbation left the observed input range; the metric judges the perturbation as much as the attribution | Reduce noise_std or pass a domain-aware perturb callable |
noise_aggregation_invalid |
Noise-tunnel aggregation outside the closed ('mean', 'mean_square', 'variance') vocabulary | Choose one of the three documented aggregations |
noise_bank_invalid |
Stored noise bank does not cover a (sample, unique leaf) draw or mismatches the leaf geometry | Provide noise_bank[sample][leaf] tensors matching every sample and unique attributed leaf |
noise_stdevs_invalid |
Noise scale is negative, misaligned with the attributed leaves, or contradictory across repeated references | Pass one nonnegative absolute scale, or a per-leaf sequence in traversal order |
noise_tunnel_composition_unsupported |
Noise tunnel over SmoothGrad (a tunnel of a tunnel) or over a trace-bound method (a static Trace leaves nothing to perturb) | Tunnel saliency directly, or pass a closed callable that re-captures from the perturbed inputs |
noise_tunnel_route_unbound |
INTERNAL tripwire: the tunnel's sugar-route per-sample overrides ran without a bound method/model (a TorchLens contract breach, never a user error) | Report this as a bug |
occlusion_geometry_invalid |
Occlusion-map geometry violation: bad window/stride spec, oversized window, bad leaf index, unknown overlap or replacement policy | Fit the window/strides to the swept axes and choose documented policies |
occlusion_pass_budget_exceeded |
Computed occlusion pass count exceeds the deterministic per-engine budget; the refusal carries the count, one measured pass time, and the projected total | Enlarge the stride, shrink the swept region, or raise max_passes explicitly |
sample_child_failed |
A wrapped method failed on one sample; the refusal names the zero-based sample and no partial result is returned | Fix the wrapped method for this input, or reduce the perturbation |
sample_invariance_violated |
Cross-sample invariance violation: value-tree topology, shapes, dtype/device, child method, target, or layer metadata changed mid-run | Keep the wrapped method shape-deterministic with fixed method/target/layer |
step_audit_invalid |
step_audit outside the closed ('off', 'per_call', 'per_chunk') ladder |
Choose 'per_call' (default under batching), 'per_chunk', or the explicit expert 'off' |
step_batch_audit_failed |
The randomized step-batching audit found batched gradients deviating from the sequential recomputation (the model couples stacked rows) | Run with step_batch_size=1 (sequential execution is the only proof) |
step_batch_layer_firings_inconsistent |
A stacked path chunk changed the target layer's firing count or does not carry the stacked batch axis | Run with step_batch_size=1 |
step_batch_size_invalid |
step_batch_size is not None or a positive integer |
Pass None for sequential execution or a small positive integer such as 8 |
step_batch_target_unsplittable |
A callable target's stacked model output tree cannot split back into logical examples | Run with step_batch_size=1, or use an int target |
text_auto_ladder_empty |
INTERNAL tripwire: the text() auto ladder finished without evaluating a single grid (a TorchLens contract breach, never a user error) | Report this as a bug |
text_bare_int_target_ambiguous |
WARNING: a bare int text() target is read as a vocab id but is also a valid position index for this input | Pass the explicit (position, vocab) tuple if a position was meant |
text_baseline_unresolvable |
text() baseline spelling unknown, misaligned, or requires a pad token the tokenizer does not have (never guessed) | Use 'auto', 'zeros', 'pad_token' (with a real pad token), an aligned embeddings tensor, or aligned token ids |
text_input_invalid |
text() input contract violation: empty text, bad n_steps spelling, or a non-single-leaf embeddings run | Pass a non-empty string and a positive int or 'auto' for n_steps |
text_input_truncated |
WARNING: explicit max_length truncated the tokenized input; scores cover the retained span only | Raise max_length to cover the full input |
text_model_unsupported |
text() could not locate a logits tensor on the model output | Use a transformers-style model whose forward returns .logits |
text_residual_above_tolerance |
WARNING: an EXPLICIT baseline spelling achieved a completeness residual above the 1% tolerance | Raise n_steps (or pass num_steps='auto'), or choose a task-appropriate baseline |
text_target_unresolvable |
text() target spelling could not resolve: multi-token string, bool, or an unsupported shape for the logits rank | Pass an int vocab id, a (position, vocab) tuple, a single-token string, a contrastive pair, or a callable |
tv_matplotlib_missing |
A tviz picture needs matplotlib, which is not installed; matplotlib resolves at CALL time (RenderError, RuntimeError lineage; every tv_* spelling experimental) |
pip install "torchlens[viz]"; the zero-dependency SVG/HTML token-strip emitters work without it |
tv_record_invalid |
A tviz display record or render request violates its construction contract: geometry/token-axis misalignment, non-finite values, a [0, 1] probability-domain claim the data violates, an unknown vocabulary token, or an unsupported save format | Fix the named field; the message states the exact violated invariant |
tv_facet_missing |
The addressed module exposes no attention pattern (or q/k/scores) facet, or no module in the trace does |
Pick a pattern-bearing module (the refusal lists them), check tl.report.doctor(model, x), or capture a transformer forward (eager attention directly; fused SDPA attention is reconstructed on a default capture) |
tv_payload_missing |
A tviz extractor needs op payloads that were not captured (selective save); the refusal names the recapture plan | Recapture with the attention ops saved (default exhaustive save suffices, fused kernels included; a selective save that skips the fused kernel's inputs needs capture=tl.options.CaptureOptions(reconstruction_ready=True)) |
tv_annotation_invalid |
An annotation kind is outside the closed four-kind vocabulary, or intervention_effect was requested without a valid CausalReceipt (only measured interventions may claim causal wording, tviz) |
Pick the kind that states what the number IS, or attach the runner's receipt |
tv_receipt_invalid |
Receipt attachment validation failed: zero fires, a moved negative control, an unmoved positive control, non-finite effects, a head-axis coordinate mismatch, a receipt GRID without the measured joint effect (tviz), or kv_groups= passed for a query-head interceptor grid |
Fix the measurement the message names; zero fires is a typed error, never a zero effect; measure the joint with one extra forward |
tv_decomposition_unclosed |
The score-decomposition terms do not reproduce the captured scores facet within tolerance, so the record refuses rather than mis-decomposing (tviz; RoPE-class families refuse per-family until term extraction covers them) | Decompose a gpt2/bert-class head, or extend the family terms |
tv_bridge_unavailable |
circuitsvis (the one supported bridge, a dormant upstream) is not installed | pip install circuitsvis, or use the native static renderers, which never depend on the bridge |
tv_bridge_payload_too_large |
The CircuitsVis payload exceeds the tested embedding ceiling; a multi-MB JSON blob stalls the notebook | Crop the views (crop_to), select fewer layers/heads, or use the native static renderers |
source_unavailable |
No captured root forward source for annotation | Re-capture a model defined in a source file; save with include_source=True |
feature_visualization_invalid |
Invalid feature optimization settings, missing/multiple tensor sites or a disconnected/non-finite objective | Use one floating input, one tensor site, a valid unit, positive steps and finite lr |
The related group_lifetime_evidence_conflict kind is governed by the merged-trace
contract (docs/reference/merged_trace_contract.md), where it is also a
MergedErrorCode member.
Adding or renaming a code is a public vocabulary change and must update this table and the
corresponding typed-door test in the same change. Constant-spelled kinds must additionally
update the enrollment table in scripts/checks/error_contract_lockstep.py.