Skip to content

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 raw ValueErrors; 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 raw TypeErrors (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 its StatKernelError, HistorySchemaError, HistoryArtifactError, WatchPlanError, ObserverEventError, SpanError, ProfilerSessionError, WatchRenderError subclasses, plus WatchLifecycleError(CaptureError).
  • trackers: TrackersError(ConfigurationError) and its SinkProtocolError, SinkDeliveryError, TagGrammarError, WatchConfigError subclasses, plus WatchRuntimeError(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) (code decode_style_unknown).
  • warning categories: PluginLoadWarning(TorchLensWarning) (soft plugin-load failures) and SynthesizedValueReadWarning(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= or include=
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.