windmill-labs/windmill · error

fclose is not supported

Error message

fclose is not supported

What it means

The Ruby parser compiled to WASM stubs out libc stdio functions it cannot implement in the wasm environment. `fdopen`/`fclose` are declared with `#[no_mangle]` as `extern "C"` shims whose only body is an unconditional `panic!`, so any Ruby code (or Ruby VM internals) that opens or closes a file stream hits this abort. It exists to fail loudly instead of silently corrupting state.

Source

Thrown at backend/parsers/windmill-parser-ruby/src/wasm_libc.rs:256

#[no_mangle]
pub unsafe extern "C" fn fputs(_s: *const c_void, _file: *mut c_void) -> c_int {
    panic!("fputs is not supported");
}

#[no_mangle]
pub unsafe extern "C" fn fputc(_c: c_int, _file: *mut c_void) -> c_int {
    panic!("fputc is not supported");
}

#[no_mangle]
pub unsafe extern "C" fn fdopen(_fd: c_int, _mode: *const c_void) -> *mut c_void {
    panic!("fdopen is not supported");
}

#[no_mangle]
pub unsafe extern "C" fn fclose(_file: *mut c_void) -> c_int {
    panic!("fclose is not supported");
}

#[no_mangle]
pub unsafe extern "C" fn fwrite(
    _ptr: *const c_void,
    _size: usize,
    _nmemb: usize,
    _stream: *mut c_void,
) -> usize {
    panic!("fwrite is not supported");
}

#[no_mangle]
pub unsafe extern "C" fn vsnprintf(
    _buf: *mut c_char,
    _size: usize,
    _format: *const c_char,
    _args: ...

View on GitHub (pinned to e474e8803c)

Solutions

  1. Remove file I/O from the Ruby code being parsed; the parser sandbox has no filesystem
  2. Rewrite the script to keep everything in memory (strings/variables) so no stream is opened or closed
  3. If stdio support is genuinely needed, implement the shim against a WASM-compatible fs (e.g. WASI) instead of panicking

Example fix

// before
result = File.open('data.txt').read
// after
result = DATA_STRING # pass content via variables/args, not file I/O
Defensive patterns

Strategy: validation

Validate before calling

// before invoking the parser, ensure the Ruby source performs no file/stream IO
fn uses_file_io(ruby_src: &str) -> bool {
    ["File.open", "IO.open", "File.new", "open(", "$stdin", "$stdout"]
        .iter().any(|p| ruby_src.contains(p))
}
if uses_file_io(ruby_source) { reject("Ruby parser sandbox forbids file IO"); }

Try / catch

match std::panic::catch_unwind(|| parse_ruby(source)) {
    Ok(res) => res,
    Err(e) => handle_parser_panic(e), // surface 'fclose is not supported' to the user as a sandbox limitation
}

Prevention

When it happens

Trigger: Calling the exported `fclose` symbol from WASM, or executing Ruby parsing code that internally calls `fclose` (e.g. Ruby IO/File operations, libraries that open streams during parse).

Common situations: Ruby script being parsed uses File.open/IO APIs or a gem that touches stdio; the parser sandbox intentionally has no filesystem, so the VM's libc call falls through to the stub.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/91d42bc00172a7b1. Report an issue: GitHub.