Use this page when a NeMo Relay setup, build, or runtime workflow does not behave as expected.
For trace incidents involving missing traces, wrong scope attachment, export failures, duplicate events, or sensitive telemetry, start with the Trace Incident Runbook.
Confirm that your environment matches Prerequisites, then rerun the binding-specific setup command from Installation.
If a command worked previously and now fails, check whether a toolchain update changed the active Rust, Python, Node.js, Go, or WebAssembly version. Recreate generated artifacts after switching versions, especially Python virtual environments, Node.js node_modules, Go build caches, and WebAssembly pkg/ output.
Run the narrowest failing build first:
If the core crate builds but another crate fails, rerun the binding-specific build or test command from Testing and Documentation. Binding crates often depend on generated native artifacts, host toolchain headers, or runtime-specific test setup.
If import nemo_relay fails, rebuild the Python environment and native extension:
Confirm that Python satisfies the supported version from Prerequisites. If multiple Python installations are available, make sure the uv environment is the one running the test or application process.
If Node.js reports a missing or incompatible native addon, reinstall dependencies from the repository root so the pretest build can regenerate the local addon:
Use Node.js Getting Started to confirm that the example runs against the generated local build, not a stale package or a globally installed copy.
The Go binding loads the shared FFI library through CGo. Build the release FFI library before running Go tests, and point the linker and runtime loader at the release target directory:
On macOS, use DYLD_LIBRARY_PATH="../../target/release" instead of LD_LIBRARY_PATH when the runtime loader cannot find the library.
Confirm that wasm-pack is installed and matches the minimum version in Prerequisites, then rerun the WebAssembly build or tests:
If generated files appear stale, remove the WebAssembly package output and rebuild it from the repository root.
A scope-stack error usually means runtime work is executing outside an active scope or on a thread that did not receive the intended scope stack.
Use Scopes and Instrument Applications Code Examples to choose the correct scope stack helper for the binding and concurrency model.
Unexpected shared scopes, middleware, or events across concurrent requests usually means more than one request is using the same scope stack. Create a fresh scope stack per request or agent, and pass that stack into async tasks, threads, callbacks, or worker boundaries that continue the request.
Use Adding Scopes and Marks and Scopes to verify that the root scope matches the request boundary.
Check whether the middleware was registered globally or scope-locally. Scope-local middleware is visible only to the owning scope and descendant scopes, and it is cleaned up when the owning scope closes.
Use Middleware, Add Middleware, and Instrument Applications Code Examples to verify the expected registration family.
Middleware runs by priority after the runtime merges global middleware with scope-local middleware from the active scope chain. If the order is surprising, check the priority assigned to each middleware entry and confirm that similarly named global and scope-local entries are registered in the intended registry.
Use Middleware and Instrument Applications Code Examples to compare registration names, priorities, and scope ownership.
A guardrail rejection is expected to stop the protected tool or LLM call. Inspect the guardrail result and confirm whether the guardrail was intended to sanitize input, sanitize output, or reject the request completely.
Use Add Middleware to verify the guardrail family and expected behavior.
Request intercepts transform the request before execution. If the original value still appears downstream, confirm that the intercept returns the changed value in the binding-specific shape and that a later request intercept is not replacing it.
Use Instrument Applications Code Examples to compare the expected request intercept callback signature for the binding.
Execution intercepts use a middleware-chain pattern. An intercept that never calls next intentionally short-circuits the original callable, while an intercept that awaits or calls next incorrectly can hang the request.
Use Middleware to confirm when an execution intercept should call next, replace the result, or stop the chain.
Confirm that the subscriber is registered before the runtime emits the events you expect. For scope-local subscribers, confirm that the active scope is the owning scope or a descendant scope.
Use Subscribers, Events, and Observability to verify lifecycle timing and event names.
Managed tool and LLM helpers populate semantic fields such as inputs, outputs, model names, and tool call IDs. Manual lifecycle calls require you to provide the relevant params explicitly.
Use Events and Instrument Applications Code Examples to verify the emitted payload shape.
An empty Agent Trajectory Interchange Format (ATIF) export usually means the
exporter subscribed after the relevant events were emitted, or the export
filter does not match the active root_uuid. Mixed trajectories usually mean
multiple agents share a root scope or the export did not filter by root scope.
Use Agent Trajectory Interchange Format (ATIF) and Observability to confirm exporter setup, event collection timing, and root-scope filtering.
When wrapping streamed LLM responses, confirm that the stream wrapper receives the provider’s terminal event and that the application drains the stream until completion. A stream that is dropped early can prevent finalizers, collectors, or subscribers from seeing the completed output.
Use Wrap LLM Calls and Provider Response Codecs to verify the expected stream event format.
JSON conversion errors usually mean the integration passed a value that cannot be represented in NeMo Relay’s JSON model, such as functions, class instances, handles, or provider-specific streaming objects.
Use Non-Serializable Data, Provider Codecs, and Using Codecs to define explicit conversions for provider-specific payloads.
If a plugin fails before runtime execution, validate configuration separately from behavior registration. Check required fields, value types, defaults, and whether the plugin is reading configuration from the expected source.
Use Validate Plugin Configuration, Design Plugin Configuration, and Register Plugin Behavior to isolate configuration problems from runtime behavior problems.
Confirm that adaptive tuning is configured for the component you expect and that the runtime path actually reaches that component. If behavior does not change, check whether the configured policy is disabled, scoped too narrowly, or not connected to the call path under test.
Use Adaptive Configuration, Adaptive Cache Governor (ACG), and Adaptive Hints to verify component names and configuration scope.
Run the wrapper command from the repository root:
If the patch still does not apply, confirm that the local checkout is clean and matches the pinned commit in third_party/sources.lock.
First reproduce the behavior through the closest core or binding-level API. If the core API behaves correctly, inspect the integration wrapper, codec, or provider adapter that translates provider calls into NeMo Relay calls.
Use Integrate into Frameworks, Wrap Tool Calls, and Wrap LLM Calls to compare the integration path with the core runtime path.