windmill-labs/windmill · error
fdopen is not supported
Error message
fdopen is not supported
What it means
fdopen is unimplemented in the Ruby parser WASM libc shim (wasm_libc.rs:251) and panics on call. Opening a file descriptor as a FILE* stream is meaningless inside the WASM sandbox — there is no filesystem — so the symbol is exported purely for link compatibility. Reaching it means the interpreter attempted to open a real I/O stream.
Source
Thrown at backend/parsers/windmill-parser-ruby/src/wasm_libc.rs:251
#[no_mangle]
pub unsafe extern "C" fn fprintf(_file: *mut c_void, _format: *const c_void, _args: ...) -> c_int {
panic!("fprintf is not supported");
}
#[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]View on GitHub (pinned to e474e8803c)
Solutions
- Ensure the parsed code path does not require file I/O — the parser sandbox supports none
- Implement fdopen in wasm_libc.rs as a stub returning a null FILE* (letting the caller handle failure) instead of panicking, then rebuild
- Upgrade windmill-parser-ruby to a version that handles missing file I/O gracefully
- Report the triggering input/backtrace upstream if fdopen should never be reached during parsing
Example fix
// before
pub unsafe extern "C" fn fdopen(_fd: c_int, _mode: *const c_void) -> *mut c_void {
panic!("fdopen is not supported");
}
// after
pub unsafe extern "C" fn fdopen(_fd: c_int, _mode: *const c_void) -> *mut c_void {
std::ptr::null_mut() // no filesystem in WASM; signal failure to the caller
} Defensive patterns
Strategy: try-catch
Validate before calling
// Reject inputs that plausibly require file I/O before parsing:
if (/File\.(open|new)|IO\.open|open\(/.test(rubySource)) {
console.warn('input references file I/O; parser sandbox has no filesystem');
} Type guard
function isFdopenPanic(e) {
return e instanceof Error && e.message.includes('fdopen is not supported');
} Try / catch
try {
const ast = rubyParser.parse(rubySource);
} catch (e) {
if (isFdopenPanic(e)) {
return { ok: false, reason: 'file-io-unsupported-in-sandbox' };
}
throw e;
} Prevention
- Remember the parser sandbox has no filesystem — never feed code paths that need file descriptors
- Stub fdopen to return null so guest code can handle the failure gracefully
- Upgrade parser builds that should never reach fdopen during pure parsing
- Capture backtraces to find which runtime code opens streams
When it happens
Trigger: The embedded Ruby parser calls C fdopen to wrap a file descriptor into a FILE*, e.g. when its runtime tries to open or wrap an I/O resource during parsing/initialization.
Common situations: Ruby parser builds whose runtime touches file descriptors; sandboxed/browser WASM with no filesystem host bindings; a dependency change that newly links fdopen.
Related errors
- clock is not supported
- fprintf is not supported
- fputs is not supported
- fputc is not supported
- fputs is not supported
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/52fd06e72d4bf264.
Report an issue: GitHub.