Dev Investigation Notes
When launching Python with PowerShell Start-Process gives unrecognized arguments, but a bat file works fine
This is a translated article. Read the original in Korean ↗
I was building a local voice assistant (voice-assistant) that stays running on Windows, transcribes speech when it hears a wake word, and reads its answers aloud. The assistant wasn't running after boot, so I tried launching pythonw directly from PowerShell to investigate. That produced error: unrecognized arguments: USB Audio. But launching it through the usual bat file worked fine with the same arguments.
Conclusion
When you pass an argument containing spaces, such as --device "KT USB Audio", through Start-Process -ArgumentList, the quotes can disappear. Python then receives the command line --device KT USB Audio. argparse takes only KT as the value of --device, rejects the remaining USB Audio as unrecognized arguments, and exits . This isn't a bug in the program or the bat file: it's a quoting bug in the command entered for testing .
How to identify it and fix it:
# 1) Check whether this is a false lead — run the actual launch path (bat) as-is
cmd /c path\to\start_assistant.bat
# 2) If you must use Start-Process: wrap the value containing spaces in an extra pair of quotes
Start-Process pythonw -ArgumentList 'main.py', '--device', '"KT USB Audio"'
# Or pass the entire command line as a single string
Start-Process pythonw -ArgumentList 'main.py --device "KT USB Audio"'
# 3) If you don't need a new window: use the call operator (&). It handles quoting for each argument
& .\venv\Scripts\python.exe main.py --device "KT USB Audio"
(The bat path and main.py are examples. The session output doesn't preserve the exact test command .)
Situation
This voice assistant runs in the background without a console window, using the venv's pythonw.exe . Its automatic startup path is VoiceAssistant.lnk in the Startup folder → start_assistant_hidden.vbs → bat → pythonw . The microphone device name is passed as the command-line argument --device "KT USB Audio" . The two spaces in that device name are the key to this incident.
The investigation proceeded by running commands one at a time in a PowerShell shell .
Symptom
- The shortcut was still in the Startup folder, but there wasn't a single
pythonw.exeprocess running - Running it directly with the console
python.exerecognized the device and reached "준비 완료" (Ready) normally - Through the bat/vbs path, no process appeared and no new log lines were written even after 25 seconds (as we'll see later, this was likely a false failure caused by the shell used for the investigation cleaning up its child processes )
- So I tried launching it directly with
pythonw, which producederror: unrecognized arguments: USB Audio
That last error seemed to explain perfectly why it died only through the pythonw path. Initially, it was treated as a "decisive clue" .
Cause
Start-Process joins the array elements passed to -ArgumentList with spaces to form a single command-line string. It doesn't automatically quote elements that contain spaces. This behavior has long been noted in an issue in the official PowerShell documentation repository (MicrosoftDocs/PowerShell-Docs#7701) and a PowerShell issue (PowerShell/PowerShell#5576). Windows processes receive the command line as a single string, and Python splits that string back up based on spaces and quotes to build sys.argv. Without the quotes, KT, USB, and Audio become separate arguments.
In the bat file, on the other hand, --device "KT USB Audio" is written with the quotes intact, so cmd passes it along as-is. Running the actual bat file with cmd /c left the command running for over 40 seconds. Because cmd waits for the pythonw launched by the bat file to exit, blocking like this meant pythonw was still alive . Checking from a separate shell confirmed that it had started normally through the bat path and reached "준비 완료. Hey Jarvis" (Ready. Hey Jarvis) .
In other words, the argparse error was a new bug introduced because the launch path created to reproduce the problem differed from the original path .
Fix
There was nothing to fix in the program or the bat file. The testing method changed.
- As soon as the clue looked suspect, I discarded the command reconstructed in PowerShell and ran the actual bat file as-is
- When passing arguments containing spaces from PowerShell, wrap the value in an extra pair of quotes, pass the entire command line as a single string, or use the
&call operator, as shown in## Conclusionabove
Before (quotes disappear):
Start-Process pythonw -ArgumentList 'main.py', '--device', 'KT USB Audio'
# Command line Python receives: main.py --device KT USB Audio
# → error: unrecognized arguments: USB Audio
After:
Start-Process pythonw -ArgumentList 'main.py', '--device', '"KT USB Audio"'
# Command line Python receives: main.py --device "KT USB Audio"
(Both examples were reconstructed from the documented behavior. They are not the exact commands entered during this session.)
Bonus — removing this quoting bug still left the boot problem
Once the quoting bug was removed, the code, bat file, and device recognition were all confirmed to work normally . But the reason it hadn't started at boot was never established in this session. The last log entry was from August 23, with no entries after that day's boot, so the investigation got only as far as observing that automatic startup hadn't run at all on this boot . The shell used for the investigation also cleaned up its child processes when the invocation ended, producing another false failure that looked like "it starts, then dies" . The lesson is the same. When the reproduction path used for debugging differs from the actual launch path, that difference creates new symptoms.
Reporter's Notes — the error message was too convincing
pythonw process python.exe, where we can see errors on-screen, instead of the windowless pythonw. If it dies there too, it's a code problem.pythonw. We'll need to isolate that path.They try launching pythonw directly with Start-Process in PowerShell, passing the device argument.
error: unrecognized arguments: USB Audio KT USB Audio, so it contains spaces. The argument splits at those spaces, and argparse, which reads the command-line arguments, takes only KT as the device name and dies because it doesn't recognize USB Audio cmd /c instead of reconstructing it in PowerShell. If we get the same error there, it's the bat file. If we don't, it's our test command.cmd /c, but the command still hasn't finished after more than 40 seconds. No error either. It's just sitting there pythonw launched by the bat file to exit. If it hasn't finished, that means pythonw is alive and running. Check from another window unrecognized arguments was a quoting bug in our Start-Process command, so we can rule it out as a candidate for the real cause Start-Process -ArgumentList just joins the argument array with spaces. It doesn't automatically quote values that contain spaces. So you need to wrap the value in another pair of quotes, like '"KT USB Audio"', or run it with the & call operator.pythonw path.