windmill-labs/windmill · error

fdopen is not supported

Error message

fdopen is not supported

What it means

The `fdopen` stub panics: associating a C stream with a file descriptor is unimplemented in the WASM libc shim. The sandbox has no real file descriptors, so the symbol is exported only for linkage and any runtime call is a fatal unsupported-operation panic.

Source

Thrown at backend/parsers/windmill-parser-java/src/wasm_libc.rs:165

#[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

  1. Remove the file-descriptor code path from the component compiled into the module; use in-memory buffers instead.
  2. Check whether the triggering input can be processed without the file I/O path (e.g. pass content directly rather than via file).
  3. Upgrade windmill-parser-java in case newer builds provide a memory-backed fdopen.
  4. Report the gap upstream if a third-party dependency requires fdopen.

Example fix

// before
FILE *f = fdopen(fd, "rb");
fread(buf, 1, n, f);

// after: operate on the in-memory buffer directly
memcpy(buf, mem_ptr, n); // no FILE* involved in WASM
Defensive patterns

Strategy: validation

Validate before calling

// Reject inputs/paths that would push the parser into file-descriptor handling; pass content in memory instead.
if (requiresFileAccess(input)) throw new Error('parser input must not require file descriptors');

Type guard

function isInlineData(x) {
  return typeof x === 'string' || x instanceof Uint8Array;
}

Try / catch

try {
  const result = parse(inlineInput);
} catch (e) {
  if (String(e).includes('fdopen is not supported')) {
    throw new Error('parser attempted file-descriptor I/O; unsupported in WASM sandbox');
  }
  throw e;
}

Prevention

When it happens

Trigger: Code compiled into the parser's WASM module calls `fdopen(fd, mode)` — usually to wrap a descriptor for reading or writing after a native open() call.

Common situations: Native components attempting real file I/O inside the sandbox; code that opens temp files or pipes and then stream-wraps the descriptor; dependencies assuming a full POSIX libc.

Related errors


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