Stream: git-wasmtime

Topic: wasmtime / issue #12172 Windows symlink oddness


view this post on Zulip Wasmtime GitHub notifications bot (Dec 16 2025 at 14:11):

wingo opened issue #12172:

This simple test fails on Windows:

use std::process;
extern crate wit_bindgen;

wit_bindgen::generate!({
    inline: r"
  package test:test;

  world test {
      include wasi:filesystem/imports@0.3.0-rc-2025-09-16;
      include wasi:cli/command@0.3.0-rc-2025-09-16;
  }
",
    additional_derives: [PartialEq, Eq, Hash, Clone],
    // Work around https://github.com/bytecodealliance/wasm-tools/issues/2285.
    features:["clocks-timezone"],
    generate_all
});

async fn test_symlink() {
    match &wasi::filesystem::preopens::get_directories()[..] {
        [(dir, _)] => {
            dir.symlink_at("..".to_string(), "t".to_string())
                .await
                .unwrap();
            dir.unlink_file_at("t".to_string()).await.unwrap();
        }
        [..] => {
            eprintln!("usage: run with one open dir");
            process::exit(1)
        }
    }
}

struct Component;
export!(Component);
impl exports::wasi::cli::run::Guest for Component {
    async fn run() -> Result<(), ()> {
        test_symlink().await;
        Ok(())
    }
}

fn main() {
    unreachable!("main is a stub");
}

The issue is that creating a symlink to .. doesn't work and fails with EPERM, whereas on POSIX platforms any permission check is only made when dereferencing the symlink.

Similarly, ln_s("does-not-exist".to_string(), "whatever".to_string).await.unwrap() fails on Windows with ENOENT. I can make a symlink to a file that does exist, however. I only tested via CI, on https://github.com/WebAssembly/wasi-testsuite/pull/195.

What's going on? Is this another area of WASI in which we have to relax the requirements?

view this post on Zulip Wasmtime GitHub notifications bot (Dec 16 2025 at 14:11):

wingo added the bug label to Issue #12172.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 17 2025 at 14:17):

wingo commented on issue #12172:

More oddness:

            dir.create_directory_at("child.cleanup".to_string())
                .await
                .unwrap();
            dir.symlink_at("../a.txt".to_string(), "child.cleanup/b".to_string())
                .await
                .unwrap();

I.e. I can't symlink to a file from a parent directory? Works on POSIX, whether making the symlink from the parent (as above) or from the child.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 18 2025 at 17:07):

fitzgen added the wasi:impl label to Issue #12172.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 18 2025 at 17:07):

fitzgen added the wasi:tests label to Issue #12172.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 18 2025 at 17:07):

fitzgen added the wasi label to Issue #12172.

view this post on Zulip Wasmtime GitHub notifications bot (Dec 18 2025 at 18:42):

alexcrichton commented on issue #12172:

I know very little about Windows symlinks myself but I wouldn't be surprised if they're different from unix-style symlinks in subtle and surprising ways. Similar to this I don't think we have much recourse other than acknolwedging the reality that symlinks are the same at 10k feet but implemented entirely differently under the hood.


Last updated: Jan 09 2026 at 13:15 UTC