Hi bytecode alliance,
I'm having trouble composing two components where one world's interface is 'use'ing a dependent interface. The specific error is as follows.
Notes
wac
as well.> wasm-tools compose salutation.wasm -d types.wasm -o sal_ty.wasm
error: failed to validate output component `sal_ty.wasm`
Caused by:
0: instance not valid to be used as export (at offset 0x10a56)
salutation/types.wit
package hotswap:salutation@0.1.0;
interface user-interface {
type tag = u64;
enum gender {
male,
female,
other
}
record user {
name: string,
id: u64,
tenant-tags: list<tag>,
gender: gender,
}
record time {
seconds: u64,
nanos: u64,
}
age-in-weeks: func(u: user, now: time) -> u32;
}
world types {
export user-interface;
}
salutation/salutation.wit
package hotswap:salutation@0.1.0;
interface salutation {
use user-interface.{user};
variant formal-honorific {
sir,
maam,
sir-maam,
custom(string)
}
get-formal-honorific: func(u: user) -> formal-honorific;
greet: func(u: user) -> string;
}
world app {
export salutation;
}
Thanks for your help!
Can you provide more steps of how to reproduce? As-is I'm not sure what the various components in play are here. It's also worth mentioning that wac
should generally be used instead of wasm-tools compose
nowadays. I know you say it's the same error message, but figured I'd reiterate anyway
Hi Alex, thanks so much for your suggestion. I've created a repo for repro (lol) here: https://github.com/estk/hotswap-example
After having the same issue with wac, i enabled logging and backtracing:
...
DEBUG wac_graph::encoding > popping type scope
DEBUG wac_graph::encoding > instance type encoded to type index 17
DEBUG wac_graph::graph > import `wasi:filesystem/preopens@0.2.0` encoded to instance index 9
DEBUG wac_graph::graph > interface `wasi:filesystem/preopens@0.2.0` is available for aliasing as instance index 9
DEBUG wac_graph::graph > instantiating package `plug:types` with arguments: [("wasi:cli/environment@0.2.0", Instance, 0), ("wasi:cli/exit@0.2.0", Instance, 1), ("wasi:io/error@0.2.0", Instance, 2), ("wasi:io/streams@0.2.0", Instance, 3), ("wasi:cli/stdin@0.2.0", Instance, 4), ("wasi:cli/stdout@0.2.0", Instance, 5), ("wasi:cli/stderr@0.2.0", Instance, 6), ("wasi:clocks/wall-clock@0.2.0", Instance, 7), ("wasi:filesystem/types@0.2.0", Instance, 8), ("wasi:filesystem/preopens@0.2.0", Instance, 9)]
DEBUG wac_graph::graph > instantiation of package `plug:types` encoded to instance index 10
DEBUG wac_graph::graph > encoding alias for instance export `hotswap:salutation/user-interface@0.1.0` of instance index 10
DEBUG wac_graph::graph > alias of export `hotswap:salutation/user-interface@0.1.0` encoded to instance index 11
DEBUG wac_graph::graph > instantiating package `socket` with arguments: [("hotswap:salutation/user-interface@0.1.0", Instance, 11), ("wasi:cli/environment@0.2.0", Instance, 0), ("wasi:cli/exit@0.2.0", Instance, 1), ("wasi:io/error@0.2.0", Instance, 2), ("wasi:io/streams@0.2.0", Instance, 3), ("wasi:cli/stdin@0.2.0", Instance, 4), ("wasi:cli/stdout@0.2.0", Instance, 5), ("wasi:cli/stderr@0.2.0", Instance, 6), ("wasi:clocks/wall-clock@0.2.0", Instance, 7), ("wasi:filesystem/types@0.2.0", Instance, 8), ("wasi:filesystem/preopens@0.2.0", Instance, 9)]
DEBUG wac_graph::graph > instantiation of package `socket` encoded to instance index 12
DEBUG wac_graph::graph > encoding alias for instance export `hotswap:salutation/salutation@0.1.0` of instance index 12
DEBUG wac_graph::graph > alias of export `hotswap:salutation/salutation@0.1.0` encoded to instance index 13
error: encoding produced a component that failed validation
Caused by:
instance not valid to be used as export (at offset 0x36d3bf)
Stack backtrace:
0: std::backtrace_rs::backtrace::libunwind::trace
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/../../backtrace/src/backtrace/libunwind.rs:116:5
1: std::backtrace_rs::backtrace::trace_unsynchronized
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: std::backtrace::Backtrace::create
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/backtrace.rs:331:13
3: anyhow::error::<impl core::convert::From<E> for anyhow::Error>::from
4: <core::result::Result<T,F> as core::ops::try_trait::FromResidual<core::result::Result<core::convert::Infallible,E>>>::from_residual
5: wac_cli::commands::plug::PlugCommand::exec::{{closure}}
6: wac::main::{{closure}}
...
thanks! I'll try to take a look at this in the near future. If you'd like as well in the meantime I think it'd be reasonable to file an issue too
Cool, ya i think this might be the same issue: https://github.com/bytecodealliance/wasm-tools/issues/1798
A bit delayed getting to this but I left a comment on the issue there about what's going wrong, let me know if the workaround of "move the types around" doesn't work for you though
That was a super helpful explanation. I just tried the suggestion, and it seems the consequences of moving the type up is that the top level component then needs to implement that interface.
My use case is roughly, team A owns the raw data and type definitions, team B, C, ... imports those and uses them in their business logic. Maybe there is some other way to accomplish this?
Ive created an issue in the wac repo here: https://github.com/bytecodealliance/wac/issues/141
Another possibility is to split interface salutation
into interface salutation
and interface salutation-types
, and I think that should work?
standby let me try that
i pushed the changes to my main branch, one sec and ill try to fix the compile err
ok, its typechecking now, but same error
interface user-types {
type tag = u64;
enum gender {
male,
female,
other
}
record user {
name: string,
id: u64,
tenant-tags: list<tag>,
gender: gender,
}
record time {
seconds: u64,
nanos: u64,
}
}
interface user {
use user-types.{user, time};
age-in-weeks: func(u: user, now: time) -> u32;
}
world types {
export user;
export user-types;
}
interface salutation-types {
variant formal-honorific {
sir,
maam,
sir-maam,
custom(string)
}
}
interface salutation {
use user-types.{user, time};
use salutation-types.{formal-honorific};
get-formal-honorific: func(u: user) -> formal-honorific;
greet: func(u: user) -> string;
}
world app {
import user;
import user-types;
export salutation-types;
export salutation;
}
if you remove export salutation-types
does it work?
(maybe export user-types
too?)
standby
world app {
import user;
export salutation;
}
cargo component build -p types
cargo component build -p salutation
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
wac plug --plug types.wasm salutation.wasm -o tysal.wasm
error: encoding produced a component that failed validation
Caused by:
instance not valid to be used as export (at offset 0x36dcea)
(same deal with user-types still imported)
hm so locally if I take the WITs you just mentioned above and delete export user-types;
, import user-types;
, and export salutation-types;
I can get a composition to work locally
did you update world types { ... }
as well to not have the export user-types
?
(and to be clear this is all still a bug in wac/wasm-compose, in the meantime I'm curious if a workaround is possible)
Sorry for the delay, was in mtgs. Ok, so yes with those changes it does work!
I've pushed a commit to the main branch with those fixes. Super interesting that that worked.
Last updated: Dec 23 2024 at 13:07 UTC