Version
main
Platform
Subsystem
watch
What steps will reproduce the bug?
$ mkdir watch-repro && cd watch-repro
$ printf 'console.log(JSON.stringify(process.title));\n' > app.cjs
Case 1: a value containing a double quote makes the child fail to start
$ NODE_OPTIONS='--title="a\"b"' node app.cjs
"a\"b"
$ NODE_OPTIONS='--title="a\"b"' node --watch app.cjs
/path/to/node: invalid value for NODE_OPTIONS (unterminated string)
Failed running 'app.cjs'. Waiting for file changes before restarting...
Case 2: a value containing a backslash is silently altered
$ NODE_OPTIONS='--title="a \\b"' node app.cjs
"a \\b"
$ NODE_OPTIONS='--title="a \\b"' node --watch app.cjs
"a b"
Completed running 'app.cjs'. Waiting for file changes before restarting...
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior? Why is that the expected behavior?
The reconstructed NODE_OPTIONS string must tokenize back to exactly the tokens that were parsed, so the child process observes the same options as a non---watch run. Round-tripping through the tokenizer is lossless only if the serializer is the exact inverse of it, which means escaping the characters the tokenizer treats specially.
What do you see instead?
The child either refuses to start with invalid value for NODE_OPTIONS (unterminated string), or starts with a silently wrong option value (a \b becomes a b).
Additional information
No response
Version
main
Platform
Subsystem
watch
What steps will reproduce the bug?
Case 1: a value containing a double quote makes the child fail to start
Case 2: a value containing a backslash is silently altered
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior? Why is that the expected behavior?
The reconstructed
NODE_OPTIONSstring must tokenize back to exactly the tokens that were parsed, so the child process observes the same options as a non---watchrun. Round-tripping through the tokenizer is lossless only if the serializer is the exact inverse of it, which means escaping the characters the tokenizer treats specially.What do you see instead?
The child either refuses to start with
invalid value for NODE_OPTIONS (unterminated string), or starts with a silently wrong option value (a \bbecomesa b).Additional information
No response