{"record":{"id":"91d42bc00172a7b1","repo":"windmill-labs/windmill","slug":"fclose-is-not-supported-91d42b","errorCode":null,"errorMessage":"fclose is not supported","messagePattern":"fclose is not supported","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/parsers/windmill-parser-ruby/src/wasm_libc.rs","lineNumber":256,"sourceCode":"\n#[no_mangle]\npub unsafe extern \"C\" fn fputs(_s: *const c_void, _file: *mut c_void) -> c_int {\n    panic!(\"fputs is not supported\");\n}\n\n#[no_mangle]\npub unsafe extern \"C\" fn fputc(_c: c_int, _file: *mut c_void) -> c_int {\n    panic!(\"fputc is not supported\");\n}\n\n#[no_mangle]\npub unsafe extern \"C\" fn fdopen(_fd: c_int, _mode: *const c_void) -> *mut c_void {\n    panic!(\"fdopen is not supported\");\n}\n\n#[no_mangle]\npub unsafe extern \"C\" fn fclose(_file: *mut c_void) -> c_int {\n    panic!(\"fclose is not supported\");\n}\n\n#[no_mangle]\npub unsafe extern \"C\" fn fwrite(\n    _ptr: *const c_void,\n    _size: usize,\n    _nmemb: usize,\n    _stream: *mut c_void,\n) -> usize {\n    panic!(\"fwrite is not supported\");\n}\n\n#[no_mangle]\npub unsafe extern \"C\" fn vsnprintf(\n    _buf: *mut c_char,\n    _size: usize,\n    _format: *const c_char,\n    _args: ...","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/parsers/windmill-parser-ruby/src/wasm_libc.rs#L238-L274","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Remove file I/O from the Ruby code being parsed; the parser sandbox has no filesystem","Rewrite the script to keep everything in memory (strings/variables) so no stream is opened or closed","If stdio support is genuinely needed, implement the shim against a WASM-compatible fs (e.g. WASI) instead of panicking"],"exampleFix":"// before\nresult = File.open('data.txt').read\n// after\nresult = DATA_STRING # pass content via variables/args, not file I/O","handlingStrategy":"validation","validationCode":"// before invoking the parser, ensure the Ruby source performs no file/stream IO\nfn uses_file_io(ruby_src: &str) -> bool {\n    [\"File.open\", \"IO.open\", \"File.new\", \"open(\", \"$stdin\", \"$stdout\"]\n        .iter().any(|p| ruby_src.contains(p))\n}\nif uses_file_io(ruby_source) { reject(\"Ruby parser sandbox forbids file IO\"); }","typeGuard":null,"tryCatchPattern":"match std::panic::catch_unwind(|| parse_ruby(source)) {\n    Ok(res) => res,\n    Err(e) => handle_parser_panic(e), // surface 'fclose is not supported' to the user as a sandbox limitation\n}","preventionTips":["Keep parsed Ruby scripts free of File/IO usage","Lint submitted scripts for IO APIs before sending them to the wasm parser","Document the parser sandbox's no-filesystem constraint for script authors"],"tags":["wasm","ruby","libc","unsupported-operation"],"backgroundTag":"wasm-unsupported-libc-call","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}