fix(wasi): component get-directories returns a guest-usable preopen list (SR-37, #405) - #406
Merged
Merged
Conversation
…-37, #405) A WASI Preview2 component run via `kilnd --wasi --component --wasi-fs <dir>` could not use any preopen: `wasi:filesystem/preopens::get-directories` wrote its `list<tuple<descriptor,string>>` result into memory adjacent to the 8-byte canonical-ABI return area (retptr+8 / retptr+20) — memory the guest never allocated. preview2 libc then registered no usable preopen and every file op returned ENOENT, without ever calling open-at. Measured (single wasm32-wasip2 component): nested_component_instances=0 (the InterComponentHandler override does not fire) and the queried dispatcher already held the preopen (preopens.len()=1) — so the defect was the return encoding, not the wiring. The working get-arguments path proves the fix: back the list return with cabi_realloc'd guest memory. This mirrors the args machinery across five sites: - kiln-foundation: HostImportHandler gains get_preopens + set_preopens_allocation. - kiln-runtime: pre_allocate_wasi_preopens + allocate_wasi_preopens_memory (N*12 entry buffer + per-path string buffers via cabi_realloc); CapabilityAware wrapper. - kiln-wasi: WasiDispatcher.preopens_alloc; get-directories writes entries into the allocation and FAILS LOUD if it was not set (no more unowned scribble). - kiln-component: ComponentInstance::pre_allocate_wasi_preopens. - kilnd: call it before the entry point, next to pre_allocate_wasi_args. With this, the guest registers the "." preopen and successfully open-at/stat's a file under it (verified by trace). Two unit oracles assert the encoding uses the allocation (not retptr+8) and fails loud without it. Note: full end-to-end file READ for #405 remains blocked on SR-38 (input-stream blocking-read writes list<u8> to a fixed unowned address — a distinct, harder defect needing on-demand cabi_realloc). #405 stays open; this lands its prerequisite. Trace: SR-37
🔍 Build Diagnostics ReportSummary
🎯 Impact AnalysisIssues in Files You Modified
Cascading Issues (Your Changes Breaking Other Files)
✅ No Issues DetectedPerfect! Your changes don't introduce any new errors or warnings, and don't break any existing code. 📊 Full diagnostic data available in workflow artifacts 🔧 To reproduce locally: # Install cargo-kiln
cargo install --path cargo-kiln
# Analyze your changes
cargo-kiln build --output json --filter-severity error
cargo-kiln check --output json --filter-severity warning |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This was referenced Jul 10, 2026
avrabe
added a commit
that referenced
this pull request
Jul 10, 2026
…) (#410) Version bump 0.4.0 → 0.4.1. Ships the complete component filesystem read/list fix for WASI Preview2 components under kilnd --wasi --component --wasi-fs: - SR-37 (#406): get-directories returns a guest-usable preopen list. - SR-38 (#407): file read (blocking-read) returns bytes in a guest-owned buffer with offset/EOF tracking. - SR-39 (#409): directory enumeration (read-directory / read-directory-entry). Together these make a preview2 component read and list files under a preopen, matching `wasmtime run --dir`. Closes #405. Trace: SR-39
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Fixes the get-directories layer of #405: a WASI Preview2 component run via
kilnd --wasi --component --wasi-fs <dir>could not use any preopen —wasi:filesystem/preopens::get-directoriesreturned a list backed by memory the guest never allocated, so preview2 libc registered no usable preopen and every file op returned ENOENT without ever calling open-at.Root cause (measured, not guessed)
For the maintainer's single
wasm32-wasip2component:nested_component_instances.len() == 0→ theInterComponentHandleroverride does not fire (ruling out the dispatcher-swap hypothesis).preopens.len() == 1).So the defect was the canonical-ABI return encoding: get-directories wrote its
list<tuple<descriptor,string>>entries atretptr+8and path strings atretptr+20, but the return area forfunc() -> list<…>is only 8 bytes. The list must be backed bycabi_realloc'd guest memory — exactly how the workingget-argumentspath does it.Fix (mirrors the proven get-arguments machinery, 5 sites)
HostImportHandler:get_preopens+set_preopens_allocation.pre_allocate_wasi_preopens+allocate_wasi_preopens_memory(N×12 entry buffer + per-path string buffers viacabi_realloc) + CapabilityAware wrapper.WasiDispatcher:preopens_alloc; get-directories writes into the allocation and fails loud if it was not set (no more unowned scribble).ComponentInstance::pre_allocate_wasi_preopens.pre_allocate_wasi_args.Verification
// rivet: verifies SR-37): the encoding uses the allocation (header points atlist_ptr, notretptr+8) and fails loud without it..preopen and successfully open-at + stat's a file under it (before: rejected immediately).Scope / honesty
This lands the prerequisite. Full end-to-end file read for #405 is still blocked on SR-38 (
input-stream.blocking-readwriteslist<u8>to a fixed unowned address — a distinct, harder defect needing on-demandcabi_realloc). #405 stays open; v0.4.1 will cut once SR-38 also lands.Trace: SR-37
🤖 Generated with Claude Code