Version
zonemaster-cli v8.0.2, Zonemaster-Engine v9.0.0, Zonemaster-LDNS 5.1.0, NL NetLabs LDNS 1.9.2. Installed from CPAN on macOS. The code is unchanged on master as of 2026-09-02
To reproduce
zonemaster-cli --profile=/no/such/file.json --dump-profile
Actual result
Loading profile from /no/such/file.json.
read_file '/no/such/file.json' - open: No such file or directory at
/Users/…/perl5/lib/perl5/Zonemaster/CLI.pm line 234.
Exit code 1.
Two problems
The message exposes an internal source path and line number rather than telling the user what to fix, and a bad command-line argument is reported as a generic error rather than a usage error.
Expected result
A localized message naming the option, and exit code 2 ($EXIT_USAGE_ERROR), consistent with how the same file already treats a bad --hints file and an invalid --sourceaddr4.
Cause
lib/Zonemaster/CLI.pm, in the --profile branch, calls read_file unguarded:
if ( $opt_profile ) {
say $fh_diag __x( "Loading profile from {path}.", path => $opt_profile );
my $json = read_file( $opt_profile );
my $foo = Zonemaster::Engine::Profile->from_json( $json );
Compare the --hints branch a little further down, which does the right thing:
try {
my $hints_text = read_file( $opt_hints ) // die "read_file failed\n";
…
}
catch { $error = $_; };
if ( defined $error ) {
print STDERR __x( "Error loading hints file: {message}", message => $error );
return $EXIT_USAGE_ERROR;
}
The same treatment applied to --profile would fix it.
Note
It would also catch malformed JSON, which currently fails through Profile->from_json with a comparable raw error.
Two smaller points, if useful in the same change
- In the
--hints branch, read_file( $opt_hints ) // die "read_file failed\n" is unreachable. File::Slurp's read_file croaks on failure in its default error mode rather than returning undef, so the // branch can never run. The surrounding try/catch is what actually catches the failure.
- Users commonly reach this by writing
--profile=~/path/file.json. The shell does not perform tilde expansion after = in that position, so the literal ~ is passed through. This is arguably correct shell behavior rather than a CLI bug, but since the message currently gives no hint, a user has little to go on. Expanding a leading ~/ in file-path options, or naming it in the error text, would remove a common stumble.
Version
zonemaster-cli v8.0.2, Zonemaster-Engine v9.0.0, Zonemaster-LDNS 5.1.0, NL NetLabs LDNS 1.9.2. Installed from CPAN on macOS. The code is unchanged on master as of 2026-09-02
To reproduce
Actual result
Two problems
The message exposes an internal source path and line number rather than telling the user what to fix, and a bad command-line argument is reported as a generic error rather than a usage error.
Expected result
A localized message naming the option, and exit code 2 ($EXIT_USAGE_ERROR), consistent with how the same file already treats a bad
--hintsfile and an invalid--sourceaddr4.Cause
lib/Zonemaster/CLI.pm, in the
--profilebranch, callsread_fileunguarded:Compare the
--hintsbranch a little further down, which does the right thing:The same treatment applied to
--profilewould fix it.Note
It would also catch malformed JSON, which currently fails through
Profile->from_jsonwith a comparable raw error.Two smaller points, if useful in the same change
--hintsbranch,read_file( $opt_hints ) // die "read_file failed\n"is unreachable.File::Slurp'sread_filecroaks on failure in its default error mode rather than returningundef, so the//branch can never run. The surroundingtry/catchis what actually catches the failure.--profile=~/path/file.json. The shell does not perform tilde expansion after=in that position, so the literal~is passed through. This is arguably correct shell behavior rather than a CLI bug, but since the message currently gives no hint, a user has little to go on. Expanding a leading~/in file-path options, or naming it in the error text, would remove a common stumble.