{"record":{"id":"50f350d15b6a5e78","repo":"windmill-labs/windmill","slug":"fclose-is-not-supported-50f350","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-java/src/wasm_libc.rs","lineNumber":170,"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":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/parsers/windmill-parser-java/src/wasm_libc.rs#L152-L188","documentation":"The `fclose` stub panics: closing a C stream is unimplemented in the WASM libc shim. Since `fopen`/`fdopen` are equally unsupported, there are no real streams to close; the symbol exists only so C code links, and a runtime call aborts the module.","triggerScenarios":"Code in the WASM module calls `fclose(stream)` on any FILE* — typically in cleanup code after (attempted) file reads/writes, or in destructors/finalizers of native components.","commonSituations":"Cleanup paths in native code that assume streams were opened successfully; error-handling branches that close a stream before unwinding; dependencies with strict open/close discipline.","solutions":["Drop the stream lifecycle code from the component compiled into the module — no streams exist in the sandbox.","Fix the earlier open/read path so cleanup that calls fclose is never reached (the real failure is upstream).","Upgrade windmill-parser-java to a version whose components avoid stdio entirely.","Guard fclose behind a non-WASM build flag if you control the source."],"exampleFix":"// before\nFILE *f = fopen(path, \"r\");\nif (f) { ...; fclose(f); }\n\n// after: read from memory; no FILE* lifecycle in WASM\nconst uint8_t *data = get_in_memory_input(&len);","handlingStrategy":"try-catch","validationCode":"if (!input || typeof input !== 'string') throw new Error('invalid parser input');","typeGuard":null,"tryCatchPattern":"try {\n  const result = parse(input);\n} catch (e) {\n  if (String(e).includes('fclose is not supported')) {\n    // usually a cleanup path after an earlier stream failure; surface the root cause\n    throw new Error('parser reached stream cleanup; streams are unsupported in WASM');\n  }\n  throw e;\n}","preventionTips":["Eliminate FILE* lifecycle code from components compiled into the module.","Treat fclose panics as symptoms of an earlier fopen/fdopen failure — fix the open path.","Keep native components free of stdio includes where possible.","Run representative parses in CI to catch stream usage before release."],"tags":["wasm","libc","file-io","fclose","panic"],"backgroundTag":"wasm-libc-stub-panic","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"}