wasmerio/wasmer · error
Internal error: $ORIGIN or ${{ORIGIN}} in RUNPATH, but no ca
Error message
Internal error: $ORIGIN or ${{ORIGIN}} in RUNPATH, but no calling module path provided What it means
locate_module expands $ORIGIN/${ORIGIN} in a RUNPATH to the directory of the calling module. If the RUNPATH contains $ORIGIN but no calling module path was provided, the code panics. The comment explains why: the only legitimate case of an empty calling_module_path is a top-level dlopen, and a dlopen'ed module has no RUNPATH-dependent requirer, so reaching this branch indicates a broken invariant in load_module_tree's invocation.
Source
Thrown at lib/wasix/src/state/linker/locator.rs:99
.as_ref()
.map(|p| p.as_ref().parent().unwrap_or_else(|| p.as_ref()));
let runtime_path = runtime_path.iter().map(|path| {
let path = path.as_ref();
let relative = path
.strip_prefix("$ORIGIN")
.or_else(|| path.strip_prefix("${ORIGIN}"));
match relative {
Some(relative) => {
let Some(calling_module_dir) = calling_module_dir else {
// This is an internal error because the only time calling_module_path
// should be empty is when loading a module through dlopen, and a
// dlopen'ed module isn't being required by another module so we don't
// have a RUNPATH to consider at all. See the invocation of
// `load_module_tree` in `load_module`.
panic!(
"Internal error: $ORIGIN or ${{ORIGIN}} in RUNPATH, but \
no calling module path provided"
);
};
Cow::Owned(PathBuf::from(
fs.relative_path_to_absolute(
calling_module_dir
.join(relative)
.to_string_lossy()
.into_owned(),
),
))
}
None => Cow::Borrowed(Path::new(path)),
}
});
// Search order is: LD_LIBRARY_PATH -> RUNPATH -> system default foldersView on GitHub (pinned to 8c4b9ee9d3)
Solutions
- Provide the calling module path when invoking load_module_tree so $ORIGIN can be expanded (see the load_module invocation site)
- If loading via dlopen, avoid $ORIGIN in RUNPATH for top-level modules or pass the .so's own directory as the calling path
- Rebuild the shared library to use an absolute RUNPATH if it is only ever dlopen'ed directly
- If it occurs during a nested require, report it as a linker bug with the module dependency chain
Example fix
// before: dlopen'ing a module whose RUNPATH uses $ORIGIN, no calling path
let m = linker.load_module("/opt/app/libfoo.so")?; // RUNPATH=$ORIGIN/../lib
// after: pass the calling module path so $ORIGIN resolves
let m = linker.load_module_with_calling_path(
"/opt/app/libfoo.so",
Path::new("/opt/app/libfoo.so"),
)?; Defensive patterns
Strategy: validation
Validate before calling
fn runpath_needs_calling_path(runpath: &str) -> bool {
runpath.contains("$ORIGIN") || runpath.contains("${ORIGIN}")
}
// before loading: if runpath_needs_calling_path(&runpath) {
// ensure load_module_tree is invoked with Some(calling_module_path)
// } Type guard
fn has_calling_path(p: &Option<PathBuf>) -> bool {
p.as_ref().map_or(false, |p| !p.as_os_str().is_empty())
} Prevention
- Pass the calling module path whenever a module's RUNPATH uses $ORIGIN
- Avoid $ORIGIN in RUNPATH for modules loaded via plain dlopen
- Prefer absolute RUNPATHs for top-level shared libraries
- Test your module dependency chain for $ORIGIN usage before deploying
When it happens
Trigger: load_module_tree invoked (via locate_module) to resolve a module whose RUNPATH entry contains $ORIGIN while calling_module_dir is None; a nested require chain where an intermediate module lost its path context.
Common situations: A .so's RUNPATH using $ORIGIN being loaded via plain dlopen rather than through the linker's module-tree loading path; a custom loader invocation passing no calling module path where RUNPATH resolution is needed; misbuilt shared library with $ORIGIN RUNPATH that should not be resolved relative to a requirer.
Related errors
- Internal error: Module with handle {module_handle:?} was alr
- Internal error: missing symbol resolution record for '{0}'.{
- Internal error: failed to resolve function {}: {e:?}
- Internal error: resolution record for symbol {name} indicate
- Internal error: function table index {index} already occupie
AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01).
Data as JSON: /api/errors/91a096f10067512b.
Report an issue: GitHub.