windmill-labs/windmill · error

vsnprintf is not supported

Error message

vsnprintf is not supported

What it means

This error comes from a hand-written libc shim in Windmill's R parser WASM crate (backend/parsers/windmill-parser-r/src/wasm_libc.rs). The R parser is compiled C/R code running inside a WASM runtime, and this file exports the libc symbols the compiled code links against. vsnprintf is intentionally left unimplemented, so if the WASM code ever calls it the stub panics with 'vsnprintf is not supported'. It exists so the module links, not to provide functionality.

Source

Thrown at backend/parsers/windmill-parser-r/src/wasm_libc.rs:276

#[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: ...
) -> c_int {
    panic!("vsnprintf is not supported");
}

#[no_mangle]
pub extern "C" fn clock_gettime(ptr: usize, new_size: usize) {
    panic!("clock_gettime is not supported");
}

// int snprintf( char* restrict buffer, size_t bufsz, const char* restrict format, ... );
#[no_mangle]
pub extern "C" fn snprintf() {
    panic!("snprintf is not supported");
}

#[no_mangle]
pub extern "C" fn __assert_fail(_: *const i32, _: *const i32, _: *const i32, _: *const i32) {
    panic!("oh no");
}

View on GitHub (pinned to e474e8803c)

Solutions

  1. Identify why the parsed R input drives vsnprintf (often a sprintf/format call in the parsed script's syntax path) and simplify or restructure the input
  2. Upgrade windmill-parser-r (or the vendored parser runtime) to a version that implements vsnprintf in wasm_libc.rs
  3. Locally patch wasm_libc.rs:276 to implement vsnprintf (or route it to the console_log helper) and rebuild the WASM parser
  4. If the panic comes from an unexpected code path, capture the WASM backtrace and report the triggering R snippet upstream

Example fix

// before (wasm_libc.rs)
pub unsafe extern "C" fn vsnprintf(_buf: *mut c_char, _size: usize, _format: *const c_char, _args: ...) -> c_int {
    panic!("vsnprintf is not supported");
}
// after: implement or delegate, e.g. minimum viable stub
pub unsafe extern "C" fn vsnprintf(_buf: *mut c_char, _size: usize, _format: *const c_char, _args: ...) -> c_int {
    0 // return 0 (no bytes written) instead of panicking
}
Defensive patterns

Strategy: try-catch

Validate before calling

// JS side, before invoking the WASM R parser:
function inputLikelySafe(rSource) {
  return typeof rSource === 'string' && rSource.length < 1_000_000 && !/sprintf|formatC/.test(rSource);
}
if (!inputLikelySafe(rSource)) throw new Error('Input may hit unsupported WASM libc paths');

Type guard

function isPanicError(e) {
  return e instanceof Error && /is not supported/.test(e.message);
}

Try / catch

try {
  const ast = rParser.parse(rSource);
} catch (e) {
  if (isPanicError(e)) {
    console.warn('R parser hit unsupported libc call; falling back');
    return fallbackParse(rSource); // e.g. regex-based or remote parse
  }
  throw e;
}

Prevention

When it happens

Trigger: The compiled R parser WASM executes a code path that calls the C library's vsnprintf (formatted output into a sized buffer, e.g. via sprintf-family internals or a formatting-heavy code path in the parser runtime).

Common situations: Parsing R code that makes the underlying C runtime reach a formatted-print path not exercised by the shim authors; running a parser/WASM version where a previously unused symbol becomes linked in; sandboxed/browser runtimes where real libc stdio is unavailable.

Related errors


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