Soimething seems to have gone wrong with CLI 3.6 on Windows:
https://forum.ionicframework.com/t/error-like-shown-below-when-running-ionic-serve-command-in-cmd-prompt/99944
https://forum.ionicframework.com/t/ionic-cli-error-after-update/99986
D:\MyCloud\git\cow-v2>ionic info --verbose
[DEBUG] CLI flags: { interactive: true, confirm: false }
[DEBUG] { cwd: 'D:\\MyCloud\\git\\cow-v2', local: true, binPath:
'C:\\Users\\Adrian\\AppData\\Roaming\\npm\\node_modules\\ionic\\bin\\ionic', libPath:
'D:\\MyCloud\\git\\cow-v2\\node_modules\\ionic\\dist\\index.js' }
[DEBUG] Loading local plugin @ionic/cli-plugin-proxy
[DEBUG] Throwing PLUGIN_NOT_INSTALLED for local @ionic/cli-plugin-proxy
[DEBUG] Loading local plugin @ionic/cli-plugin-ionic-angular
[DEBUG] Getting plugin info for ionic
[DEBUG] Checking for latest plugin version of ionic@latest.
[DEBUG] Getting plugin info for @ionic/cli-plugin-ionic-angular
[DEBUG] Checking for latest plugin version of @ionic/cli-plugin-ionic-angular@latest.
[DEBUG] New daemon pid: 39216
events.js:160
throw er; // Unhandled 'error' event
^
Error: spawn C:\Program Files\nodejs\node.exe ENOENT
at notFoundError (D:\MyCloud\git\cow-v2\node_modules\cross-spawn\lib\enoent.js:11:11)
at verifyENOENT (D:\MyCloud\git\cow-v2\node_modules\cross-spawn\lib\enoent.js:46:16)
at ChildProcess.cp.emit (D:\MyCloud\git\cow-v2\node_modules\cross-spawn\lib\enoent.js:33:19)
at Process.ChildProcess._handle.onexit (internal/child_process.js:215:12)
https://forum.ionicframework.com/t/error-after-update-to-ionic-3-6/99967
[WARN] You are not in an Ionic project directory. Project context may be missing.
cli packages:
@ionic/cli-utils : 1.6.0 (C:\Users\HP\AppData\Roaming\npm\node_modules\ionic\node_modules\@ionic\cli-utils)
ionic (Ionic CLI) : 3.6.0 (C:\Users\HP\AppData\Roaming\npm\node_modules\ionic)
System:
Node : v8.1.2
OS : Windows 10
npm : 5.0.3
(Last one got it working)
I think I found the cause:
ionic daemon passes process.argv[0] to cross-spawn with shell: true . process.argv[0] contains node's full path which contains spaces (C:\Program Files\nodejs\node.exe) .shell: true on node 6+, it passes the arguments directly to child_process.spawn without escaping the spaces in the command.cmd.exe because it would break other things: nodejs/node#7367cmd.exe tries to execute 'C:\Program` and fails.Removing the shell argument fixes it for me. It was added in this commit calling it better windows behavior.
@dwieeb : can you explain what did that fix? And could it be reverted?
Alternatively, should cross-spawn be changed to escape the command even if node supports shell: true natively?
I filed a bug with cross-spawn: IndigoUnited/node-cross-spawn#77
@imgx64 Thanks for debugging so thoroughly. I was testing this on windows and it seems shell: true was required to get the background process functionality to work. I'll test this further.
@imgx64 I've never been able to reproduce this issue, FYI. I am on Windows 10 using command prompt.
I used shell: true because if I don't, the daemon process isn't long-lasting. You can confirm this by running ionic --verbose commands, it will say "New daemon pid:" every time with shell: false.
Here are the args with shell: true, notice the double quotes around the paths:
spawnargs:
[ 'C:\\WINDOWS\\system32\\cmd.exe',
'/s',
'/c',
'"C:\\WINDOWS\\system32\\cmd.exe /s /c ""C:\\Program Files\\nodejs\\node.exe" "C:\\Users\\dwieeb\\AppData\\Roaming\\npm\\node_modules\\ionic\\bin\\ionic" "daemon" "--verbose" "--no-interactive" "--log-timestamps" "--interval" "10"""' ],
@imgx64 If you find the daemon.js file in the @ionic/cli-utils npm package on your local machine, you can play with the cross-spawn options. Also console.log(p) like I did to see the spawn args.
It just seems like there's different behavior from machine to machine somehow.
@dwieeb For some inexplicable reason, the issue disappeared after deleting node_modules and running npm install again. I'm certain I tried that yesterday and it didn't work.
I did a little more investigation and found that [email protected] (required by @ionic/[email protected], which is required by [email protected]) quotes the command passed to shell correctly, but [email protected] (required by @ionic/[email protected]) does not quote it. Maybe there's a bug in npm which made @ionic/cli-utils import [email protected]? I really can't tell, and I'm unable to reproduce the issue anymore.
Try to install @ionic/cli-utils, this fixed the issue for me.
npm install @ionic/cli-utils
@imgx64 Very frustrating! That gives me a lot more to work with, though. I will debug this tonight when I have access to Windows again. Thanks so much for working with me on this 🎉
@imgx64 Not able to reproduce with cross-spawn 4 _or_ 5. It puts double quotes around each argument in both versions, at least for me.
@dwieeb What does the below output?
mkdir test
cd test
npm init --yes
npm install [email protected]
node
> require('cross-spawn').spawn('C:\\Program Files\\nodejs\\node.exe', [], {shell:true})
@imgx64 For me, I also have the original problem sometimes now, this returns:
PS C:\Users\Jan\Documents\test> node
> require('cross-spawn').spawn('C:\\Program Files\\nodejs\\node.exe', [], {shell:true})
ChildProcess {
domain:
Domain {
domain: null,
_events: { error: [Function: debugDomainError] },
_eventsCount: 1,
_maxListeners: undefined,
members: [] },
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
_closesNeeded: 3,
_closesGot: 0,
connected: false,
signalCode: null,
exitCode: null,
killed: false,
spawnfile: 'C:\\WINDOWS\\system32\\cmd.exe',
_handle: Process { owner: [Circular], onexit: [Function], pid: 17796 },
spawnargs:
[ 'C:\\WINDOWS\\system32\\cmd.exe',
'/d',
'/s',
'/c',
'"C:\\Program Files\\nodejs\\node.exe"' ],
pid: 17796,
stdin:
Socket {
connecting: false,
_hadError: false,
_handle:
Pipe {
bytesRead: 0,
_externalStream: [External],
fd: -1,
writeQueueSize: 0,
owner: [Circular],
onread: [Function: onread],
reading: true },
_parent: null,
_host: null,
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: [Object],
length: 0,
pipes: null,
pipesCount: 0,
flowing: null,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: false,
domain:
Domain {
domain: null,
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
members: [] },
_events:
{ end: [Object],
finish: [Function: onSocketFinish],
_socketEnd: [Function: onSocketEnd] },
_eventsCount: 3,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object] },
writable: true,
allowHalfOpen: false,
_bytesDispatched: 0,
_sockname: null,
_writev: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
[Symbol(asyncId)]: 109,
[Symbol(bytesRead)]: 0 },
stdout:
Socket {
connecting: false,
_hadError: false,
_handle:
Pipe {
bytesRead: 0,
_externalStream: [External],
fd: -1,
writeQueueSize: 0,
owner: [Circular],
onread: [Function: onread],
reading: true },
_parent: null,
_host: null,
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: [Object],
length: 0,
pipes: null,
pipesCount: 0,
flowing: null,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain:
Domain {
domain: null,
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
members: [] },
_events:
{ end: [Object],
finish: [Function: onSocketFinish],
_socketEnd: [Function: onSocketEnd],
close: [Function] },
_eventsCount: 4,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object] },
writable: false,
allowHalfOpen: false,
_bytesDispatched: 0,
_sockname: null,
_writev: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
[Symbol(asyncId)]: 110,
[Symbol(bytesRead)]: 0 },
stderr:
Socket {
connecting: false,
_hadError: false,
_handle:
Pipe {
bytesRead: 0,
_externalStream: [External],
fd: -1,
writeQueueSize: 0,
owner: [Circular],
onread: [Function: onread],
reading: true },
_parent: null,
_host: null,
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: [Object],
length: 0,
pipes: null,
pipesCount: 0,
flowing: null,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain:
Domain {
domain: null,
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
members: [] },
_events:
{ end: [Object],
finish: [Function: onSocketFinish],
_socketEnd: [Function: onSocketEnd],
close: [Function] },
_eventsCount: 4,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object] },
writable: false,
allowHalfOpen: false,
_bytesDispatched: 0,
_sockname: null,
_writev: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
[Symbol(asyncId)]: 111,
[Symbol(bytesRead)]: 0 },
stdio:
[ Socket {
connecting: false,
_hadError: false,
_handle: [Object],
_parent: null,
_host: null,
_readableState: [Object],
readable: false,
domain: [Object],
_events: [Object],
_eventsCount: 3,
_maxListeners: undefined,
_writableState: [Object],
writable: true,
allowHalfOpen: false,
_bytesDispatched: 0,
_sockname: null,
_writev: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
[Symbol(asyncId)]: 109,
[Symbol(bytesRead)]: 0 },
Socket {
connecting: false,
_hadError: false,
_handle: [Object],
_parent: null,
_host: null,
_readableState: [Object],
readable: true,
domain: [Object],
_events: [Object],
_eventsCount: 4,
_maxListeners: undefined,
_writableState: [Object],
writable: false,
allowHalfOpen: false,
_bytesDispatched: 0,
_sockname: null,
_writev: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
[Symbol(asyncId)]: 110,
[Symbol(bytesRead)]: 0 },
Socket {
connecting: false,
_hadError: false,
_handle: [Object],
_parent: null,
_host: null,
_readableState: [Object],
readable: true,
domain: [Object],
_events: [Object],
_eventsCount: 4,
_maxListeners: undefined,
_writableState: [Object],
writable: false,
allowHalfOpen: false,
_bytesDispatched: 0,
_sockname: null,
_writev: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
[Symbol(asyncId)]: 111,
[Symbol(bytesRead)]: 0 } ],
emit: [Function] }
> Error: spawn C:\Program Files\nodejs\node.exe ENOENT
at notFoundError (C:\Users\Jan\Documents\test\node_modules\cross-spawn\lib\enoent.js:11:11)
at verifyENOENT (C:\Users\Jan\Documents\test\node_modules\cross-spawn\lib\enoent.js:46:16)
at ChildProcess.cp.emit (C:\Users\Jan\Documents\test\node_modules\cross-spawn\lib\enoent.js:33:19)
at Process.ChildProcess._handle.onexit (internal/child_process.js:197:12)
>
@janpio
Yeah, that's what I get too. I was wondering if it works on @dwieeb 's machine.
If you can reproduce the original issue (throw er; // Unhandled ‘error’ event), please run npm ls cross-spawn on the same project.
Sure:
PS C:\Users\Jan\Documents\stromzaehler> ionic info
\ Gathering environment info
events.js:182
throw er; // Unhandled 'error' event
^
Error: spawn C:\Program Files\nodejs\node.exe ENOENT
at notFoundError (C:\Users\Jan\Documents\stromzaehler\node_modules\cross-spawn\lib\enoent.js:11:11)
at verifyENOENT (C:\Users\Jan\Documents\stromzaehler\node_modules\cross-spawn\lib\enoent.js:46:16)
at ChildProcess.cp.emit (C:\Users\Jan\Documents\stromzaehler\node_modules\cross-spawn\lib\enoent.js:33:19)
at Process.ChildProcess._handle.onexit (internal/child_process.js:197:12)
PS C:\Users\Jan\Documents\stromzaehler> npm ls cross-spawn
ionic-hello-world@ C:\Users\Jan\Documents\stromzaehler
+-- @ionic/[email protected]
| +-- [email protected]
| `-- [email protected]
| `-- [email protected]
+-- @ionic/[email protected]
| +-- @ionic/[email protected]
| | `-- UNMET DEPENDENCY cross-spawn@^4.0.2
| `-- [email protected] extraneous
+-- @ionic/[email protected]
| `-- [email protected] extraneous
`-- [email protected]
`-- [email protected] extraneous
npm ERR! extraneous: [email protected] C:\Users\Jan\Documents\stromzaehler\node_modules\@ionic\cli-plugin-cordova\node_m
odules\cross-spawn
npm ERR! missing: cross-spawn@^4.0.2, required by @ionic/[email protected]
npm ERR! extraneous: [email protected] C:\Users\Jan\Documents\stromzaehler\node_modules\@ionic\cli-plugin-ionic-angular\
node_modules\cross-spawn
npm ERR! extraneous: [email protected] C:\Users\Jan\Documents\stromzaehler\node_modules\ionic\node_modules\cross-spawn
PS C:\Users\Jan\Documents\stromzaehler>
And so the pretty colors don't get lost:

What @rluckez wrote actually worked for me as well, by the way:
Try to install @ionic/cli-utils, this fixed the issue for me.
npm install @ionic/cli-utils
Interesting. cross-spawn@^4.0.2 was listed as an "UNMET DEPENDENCY" in @janpio's node_modules. It seems this is an npm bug as well? It failed to install the appropriate version for @ionic/cli-utils.
So @imgx64, after using cross-spawn 5 ...
On Windows,
detached: true, shell: true, node exits silently with exit code 1.detached: true, shell: false, things behave as expected, except child processes of the daemon process (the npm info commands) get spun up into a dozen cmd.exe windows... very unsightly. For some reason, even with shell: false on these subcommands (see https://github.com/ionic-team/ionic-cli/blob/master/packages/cli-utils/src/lib/utils/shell.ts#L31), the spawnargs contain cmd.exe:```
spawnargs:
[ 'C:\\WINDOWS\\system32\\cmd.exe',
'/d',
'/s',
'/c',
'"npm "view" "ionic" "dist-tags.latest" "--json""' ],
```
detached: false of course kills the child process when the parent process has completed.Since option 2 seems to be what we want, I could do HTTP requests to the npm registry instead of using child processes in the daemon process.
According to this comment I _should_ be using shell: true and putting quotes around the path.
So I think the best course of action is to use cross-spawn 5, and use:
crossSpawn.spawn(`"${process.execPath}"`, [process.argv[1], 'daemon', ...]
I tested this with detached: false, which apparently we _do_ want for subprocesses using shell in Windows. It finally works as I expect.
@imgx64 I believe this commit fixes the issue: https://github.com/ionic-team/ionic-cli/commit/1beb4553a7c891cbfa217264ac531e3d7cbaa510
npm i -D -E [email protected]
This solution works for me
npm i -D -E [email protected]
This solution works for me.
thank you @zurich316
We must be getting a bunch of people from Google regarding that websocket issue, as ws has nothing to do with the original issue, though the error is similar.
For the websocket issue:
@ionic/app-scripts, which has ws pinned. You do not need to install it yourself. (the commit for this fix is here https://github.com/ionic-team/ionic-app-scripts/commit/db0cc4de9194bbf9b825c4934ea48a7510a9f5fb)ws yourself at 3.3.2 for now. (npm i -D -E [email protected])
Most helpful comment
npm i -D -E [email protected]
This solution works for me