Skip to content

Refuse an album name and a flag pair that cannot mean anything - #44

Merged
ergofobe merged 1 commit into
mainfrom
issue-41-album-args
Sep 16, 2026
Merged

ergofobe merged 1 commit into
mainfrom
issue-41-album-args

Conversation

@ergofobe

Copy link
Copy Markdown
Owner

The write-side half of the album hardening #42 / 4a3cc7a did for reading. Two
arguments imogen album accepted and should not have.

#41 — -d and --clear-description together

album update Holiday -d "new text" --clear-description parsed, albums::update
took the clearing branch, and the description asked for was dropped without a word,
exit 0. edit has had conflicts_with = "clear_description" on the same pair since
#32. album update now declares it the same way — the inconsistency between the two
commands was the defect, so it is the same attribute rather than a second way of
saying it.

#43 — a name no reference can pick

album create "", " ", or album update --name with either, wrote an album
reachable only by its id: albums_for refuses an empty reference when reading, and
no non-empty reference matches an empty name, so album show, add, remove,
delete and --album were all shut out of it.

context::album_name is the mirror of that read-side guard, refusing before
anything reaches the wire. It trims as well, because named_album compares the
stored name trimmed: a padded name would otherwise answer to something it is not
spelled as, and album create " Trip " would leave an album a listing cannot tell
from the one upload --album Trip makes. album_or_create already created under
the trimmed name, so the two doors into an album's name now agree — creation and
lookup settle on the same string.

On update the refusal runs before find_album, so a rename that could never be
undone by name stops the command whatever else it was asked to change.

Filing into an album is still a name and not a search: nothing here touches
named_album's tiers.

Tests

Written first; all five failed on main before the fix.

Test Failed on main with
cli::an_album_description_cannot_be_both_written_and_removed the pair parsed
albums::an_album_cannot_be_created_without_a_name the empty name was created
albums::an_album_cannot_be_renamed_to_nothing the empty name was patched
albums::a_new_album_is_created_under_the_trimmed_name sent " Trip\n"
albums::a_rename_is_stored_trimmed_too sent " Trip\n"

The two refusal tests assert stub.calls().is_empty() — the refusal is before the
wire, not a rejection from the server. The parse test also asserts each flag alone
still parses, so a conflicts_with naming the wrong id cannot pass unnoticed.

src/commands/albums.rs gains its own stub server, as context.rs and
commands/people.rs each carry one; no shared test component was introduced.

Both audiences

The refusal is a plain anyhow error down the one path main::report already
renders twice. Checked against the release binary with an unreachable server, which
was never contacted:

$ imogen album create "   "
error: An album needs a name — an album with none could only ever be named by its id
$ imogen --json album create "   "
{ "causes": [], "error": "An album needs a name — …" }

Both exit 1. album update -d … --clear-description is clap's own refusal, exit 2.

Verify

cargo test --locked && cargo fmt --check && cargo clippy --all-targets --locked -- -D warnings && cargo build --release --locked — green. 154 unit + 4 integration
tests pass.

Nothing on the wire changes and the SDK pin does not move.

Closes #41
Closes #43

🤖 Generated with Claude Code

Two ways `imogen album` accepted an argument it should have refused, both the
write-side counterpart of #38's reading.

`album update -d "new text" --clear-description` parsed happily, `albums::update`
took the clearing branch, and the description asked for was discarded without a
word, exit 0. `edit` has carried `conflicts_with = "clear_description"` since #32;
`album update` declares the same pair and did not, so the same contradiction was a
refusal in one command and a silent loss in the other. The fix is that attribute,
not a second way of saying it: the inconsistency between the two was the defect.

`album create ""` — or "   ", or `--name` the same on `update` — wrote an album no
reference could ever pick again. `albums_for` refuses an empty reference when
reading, and no non-empty one matches an empty name, so `album show`, `add`,
`remove`, `delete` and `--album` were all shut out of it and only its id was left.
`album_name` is the mirror of that guard on the side that writes, refusing before
anything reaches the wire.

It trims as well as refuses, because `named_album` compares the *stored* name
trimmed: a name written with padding would otherwise answer to something it is not
spelled as, and `album create " Trip "` would leave an album a listing cannot tell
from the one `upload --album Trip` makes. `album_or_create` already created under
the trimmed name; the two doors into an album's name now agree.

On `update` the refusal comes before the album is even looked up, so a rename that
could never be undone by name stops the command whatever else it was asked to
change.

Closes #41
Closes #43

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ergofobe
ergofobe merged commit 9460959 into main Sep 16, 2026
2 checks passed
@ergofobe
ergofobe deleted the issue-41-album-args branch September 16, 2026 03:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

imogen album create "" makes an album no name can reach album update -d with --clear-description silently drops the description

1 participant