Repository: deno
Issue: Can't write files in Emscripten's NODEFS when using Pyodide
Labels: bug,node compat

Version: Deno 1.43.1

This is an issue I have originally rised with Pyodide here: https://github.com/pyodide/pyodide/issues/4647, and with Emscripten here: https://github.com/emscripten-core/emscripten/issues/21673

However, as it appears to come from some low-level mismatch between Node and Deno in the `fs` module, I'm raising it here as well.

---

This is an example Node.js program that uses Pyodide to write a file in a NODEFS-mounted folder:

```
// test.mjs
// run with: node test.mjs

import { loadPyodide } from "pyodide"

const pyodide = await loadPyodide()

pyodide.setStdout()
pyodide.setStderr()

pyodide.FS.mount(pyodide.FS.filesystems.NODEFS, { root: "." }, "/home/pyodide")

await pyodide.runPythonAsync("from pathlib import Path; Path('out.txt').write_text('Hello, World!')");
```

This works as expected, the file `out.txt` with contents `Hello, World!` is written to current folder.

---

The same code, adjusted to run with Deno:

```
// test.ts
// run with: deno run --allow-write --allow-read --allow-net test.ts

import { loadPyodide } from "npm:pyodide/pyodide.mjs"

const pyodide = await loadPyodide()

pyodide.setStdout()
pyodide.setStderr()

pyodide.FS.mount(pyodide.FS.filesystems.NODEFS, { root: "." }, "/home/pyodide")

await pyodide.runPythonAsync("from pathlib import Path; Path('out.txt').write_text('Hello, World!')");
```

This, however, crashes with the following output:

```
error: Uncaught (in promise) PythonError: OSError: raw write() returned invalid length 2831100 (should have been between 0 and 13)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/lib/python311.zip/_pyodide/_base.py", line 573, in eval_code_async
    await CodeRunner(
  File "/lib/python311.zip/_pyodide/_base.py", line 393, in run_async
    coroutine = eval(self.code, globals, locals)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<exec>", line 1, in <module>
  File "/lib/python311.zip/pathlib.py", line 1078, in write_text
    with self.open(mode='w', encoding=encoding, errors=errors, newline=newline) as f:
OSError: raw write() returned invalid length 9188352 (should have been between 0 and 13)

    at new_error (file:///Users/jp/Playground/pyodide-test/node_modules/.deno/pyodide@0.25.0/node_modules/pyodide/pyodide.asm.js:9:10014)
    at <anonymous> (wasm://wasm/02257296:1:1412707)
    at <anonymous> (wasm://wasm/02257296:1:1441695)
    at _PyEM_TrampolineCall_JS (file:///Users/jp/Playground/pyodide-test/node_modules/.deno/pyodide@0.25.0/node_modules/pyodide/pyodide.asm.js:9:120166)
    at <anonymous> (wasm://wasm/02257296:1:1717397)
    at <anonymous> (wasm://wasm/02257296:1:2663102)
    at <anonymous> (wasm://wasm/02257296:1:1983263)
    at <anonymous> (wasm://wasm/02257296:1:1718654)
    at <anonymous> (wasm://wasm/02257296:1:1719359)
    at <anonymous> (wasm://wasm/02257296:1:1719521)
    at <anonymous> (wasm://wasm/02257296:1:2525605)
    at <anonymous> (wasm://wasm/02257296:1:2549761)
    at <anonymous> (wasm://wasm/02257296:1:1719817)
    at <anonymous> (wasm://wasm/02257296:1:1718937)
    at <anonymous> (wasm://wasm/02257296:1:1439596)
    at Object.Module.callPyObjectKwargs (file:///Users/jp/Playground/pyodide-test/node_modules/.deno/pyodide@0.25.0/node_modules/pyodide/pyodide.asm.js:9:64297)
    at Object.Module.callPyObject (file:///Users/jp/Playground/pyodide-test/node_modules/.deno/pyodide@0.25.0/node_modules/pyodide/pyodide.asm.js:9:65365)
    at Timeout.wrapper [as _onTimeout] (file:///Users/jp/Playground/pyodide-test/node_modules/.deno/pyodide@0.25.0/node_modules/pyodide/pyodide.asm.js:9:32855)
    at cb (ext:deno_node/internal/timers.mjs:64:31)
    at eventLoopTick (ext:core/01_core.js:204:13)
```