Skip to content

Bare --option with no value silently passes "true" to String parameters #128

Description

@dblevins

Summary

When a String-typed @Option is passed on the command line without a value (e.g., --name instead of --name=foo), Crest treats it as a boolean flag and passes the string "true" as the value. This can silently corrupt data.

Reproduction

Given a command method:

@Command
public void update(@Option("name") final String name) {
    if (name != null) record.setName(name);
}

Running:

myapp update --subscription-start=2026-05-20 --name

Results in name being set to "true" instead of erroring.

Root cause

Arguments.java line ~100 — when an arg has no = and is not --no-*, the value is unconditionally set to "true":

} else {
    if (arg.startsWith("--no-")) {
        name = arg.substring(5);
        value = "false";
    } else {
        name = arg.substring(prefix.length());
        value = "true";
    }
}

This is correct for boolean/flag parameters but incorrect for String (and likely other non-boolean types).

Expected behavior

When the target parameter type is String, a bare --name with no = should raise an error indicating a missing value, e.g.:

Missing value for option: --name

Impact

This caused a Salesforce quote name to be overwritten with the literal string "true" in production.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions