Skip to content

Replace panicking unwrap with descriptive errors in plugin-api#1134

Merged
jeffcharles merged 2 commits intobytecodealliance:mainfrom
UNORTHOD0xd:fix/plugin-api-runtime-panic
Feb 12, 2026
Merged

Replace panicking unwrap with descriptive errors in plugin-api#1134
jeffcharles merged 2 commits intobytecodealliance:mainfrom
UNORTHOD0xd:fix/plugin-api-runtime-panic

Conversation

@UNORTHOD0xd
Copy link
Contributor

Summary

compile_src() and invoke() in javy-plugin-api call .unwrap() on RUNTIME.get(), which panics with an opaque message when the runtime has not been initialized:

thread '<unnamed>' panicked at crates/plugin-api/src/lib.rs:174:42:
called `Option::unwrap()` on a `None` value

This makes debugging difficult for plugin authors and host integrators, as the panic message gives no indication of what went wrong or how to fix it.

Changes

Replace the bare .unwrap() calls with .ok_or_else() returning a descriptive anyhow error that names the uninitialized runtime and points to initialize_runtime as the required precondition:

Javy runtime not initialized. Ensure `initialize_runtime` is called before `compile_src`.

Both functions already return Result<T>, so this is a non-breaking change with no new dependencies.

Context

This issue was encountered while building a Chainlink CRE workflow plugin. The javy host (v5.0.4) called compile_src before initialize_runtime, producing the opaque panic. The resulting error message (called Option::unwrap() on a None value) with a path pointing into the Cargo registry gave no actionable information about the root cause.

Copy link
Collaborator

@jeffcharles jeffcharles left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can run make ci to ensure your code will pass the linter and tests.

// bytecode than if it were set to `false`.
let runtime = unsafe { RUNTIME.get().unwrap() };
let runtime = unsafe { RUNTIME.get() }
.ok_or_else(|| anyhow!("Javy runtime not initialized. Ensure `initialize_runtime` is called before `compile_src`."))?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We document requiring running javy init-plugin ... here so I'd recommend updating the error messages to include that javy init-plugin should be invoked. init-plugin initializes the runtime and saves the runtime into a series of data segments in the Wasm module that it outputs that RUNTIME references. Hypothetically someone could use this as a Rust library but we recommend using the lower-level javy crate for that use-case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call — updated both error messages to reference javy init-plugin instead. Thanks for the pointer to the extending docs.

@UNORTHOD0xd UNORTHOD0xd force-pushed the fix/plugin-api-runtime-panic branch from e3dffcc to be28bd7 Compare February 11, 2026 03:40
…invoke

compile_src() and invoke() panic with an opaque "called Option::unwrap()
on a None value" when RUNTIME has not been initialized. This makes
debugging difficult for plugin authors and host integrators, as the panic
message gives no indication of what went wrong or how to fix it.

Replace the bare .unwrap() calls with .ok_or_else() returning a
descriptive anyhow error that names the uninitialized runtime and points
to initialize_runtime as the required precondition. Both functions
already return Result, so this is a non-breaking change.
@UNORTHOD0xd UNORTHOD0xd force-pushed the fix/plugin-api-runtime-panic branch from be28bd7 to 8dd2e0c Compare February 11, 2026 03:43
@jeffcharles
Copy link
Collaborator

Looks like one of the integration tests is failing due to no longer trapping when the plugin is uninitialized. The test should be updated to read from the linear memory at the offset given by the return value. The first 4 bytes is the result variant which should be a non-zero value to indicate an error state.

@UNORTHOD0xd
Copy link
Contributor Author

Thanks @jeffcharles for the pointer! Updated the test to read the result discriminant from linear memory instead of expecting a trap. Should be green now.

Now that compile_src returns a Result instead of panicking,
the compile-src export no longer traps on an uninitialized
runtime. Update the test to read the result discriminant from
linear memory and assert a non-zero (error) value.
@jeffcharles
Copy link
Collaborator

I'm seeing a formatting failure in CI. Again, would recommend running make ci just to double-check everything passes. We have some contributing docs in the docs directory you can review if you're finding that you're seeing errors around tools not being installed when running that.

Again though, thank you for submitting this PR! The better error message should help steer other plugin developers toward running init-plugin.

@UNORTHOD0xd UNORTHOD0xd force-pushed the fix/plugin-api-runtime-panic branch from 26c68c0 to f51dba8 Compare February 12, 2026 16:26
@UNORTHOD0xd
Copy link
Contributor Author

The failure was just cargo fmt wanting the .get_memory() chain split across lines. CI should be green now. No problem, just happy to contribute. Cheers!

Copy link
Collaborator

@jeffcharles jeffcharles left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you again, this is a much nicer user experience and also helpful for providing direct feedback to LLMs

@jeffcharles jeffcharles merged commit 6605f4e into bytecodealliance:main Feb 12, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments