What happens
Arguments.TryResolveOutput (IconHelper/Arguments.cs:~110-128) rejects an --output only when it names an existing file. It never checks that the folder can actually be created. ProcessDirectory then calls Directory.CreateDirectory(outputDirectory) (IconHelper/IconHelper.cs:112) and Directory.GetFiles(inputDirectory, "*") (line 116). Both calls sit outside the per-file try/catch, and Run has no handler of its own, so any IO or permission failure escapes as an unhandled exception.
Repro on a Release build of main (0857cce):
# the parent "semi.png" is a file, not a folder
iconhelper -i in1 -o in1/semi.png/sub
Unhandled exception. System.IO.DirectoryNotFoundException: Could not find a part of the path '.../in1/semi.png/sub'
at ... (full stack trace)
exit=134
iconhelper -i in1 -o /proc/iconout
Unhandled exception. System.IO.FileNotFoundException ...
exit=134
The same thing happens for the common real-world case of an output folder the user has no permission to create (UnauthorizedAccessException), and for an input folder that exists but can't be listed (through GetFiles).
Why it matters
- The README exit-code table and CLAUDE.md define exit
1 for unusable arguments. CLAUDE.md (line ~124) notes that this same crash was already fixed for a missing --input. Scripts that branch on the exit code instead get 134 (SIGABRT), plus a stack trace in place of a one-line message.
Suggested fix
- Catch
IOException and UnauthorizedAccessException around CreateDirectory and GetFiles, either in ProcessDirectory or in Run. Print a single-line message naming the path and the reason, and return ExitInvalidArguments.
- Alternatively, try creating the folder during
Validate, so the error comes out alongside the other argument errors.
Acceptance criteria
-o <existing-file>/sub, an uncreatable output folder, and an unlistable input folder each print a clean error and exit 1, with no stack trace.
- Tests cover at least the file-as-parent case, which is portable and needs no permissions setup.
What happens
Arguments.TryResolveOutput(IconHelper/Arguments.cs:~110-128) rejects an--outputonly when it names an existing file. It never checks that the folder can actually be created.ProcessDirectorythen callsDirectory.CreateDirectory(outputDirectory)(IconHelper/IconHelper.cs:112) andDirectory.GetFiles(inputDirectory, "*")(line 116). Both calls sit outside the per-file try/catch, andRunhas no handler of its own, so any IO or permission failure escapes as an unhandled exception.Repro on a Release build of main (0857cce):
The same thing happens for the common real-world case of an output folder the user has no permission to create (
UnauthorizedAccessException), and for an input folder that exists but can't be listed (throughGetFiles).Why it matters
1for unusable arguments. CLAUDE.md (line ~124) notes that this same crash was already fixed for a missing--input. Scripts that branch on the exit code instead get 134 (SIGABRT), plus a stack trace in place of a one-line message.Suggested fix
IOExceptionandUnauthorizedAccessExceptionaroundCreateDirectoryandGetFiles, either inProcessDirectoryor inRun. Print a single-line message naming the path and the reason, and returnExitInvalidArguments.Validate, so the error comes out alongside the other argument errors.Acceptance criteria
-o <existing-file>/sub, an uncreatable output folder, and an unlistable input folder each print a clean error and exit 1, with no stack trace.