Skip to content

fix(cli): report invalid flag values as usage errors - #106

Merged
sergiught merged 1 commit into
mainfrom
fix/flag-value-usage-errors
Aug 3, 2026
Merged

fix(cli): report invalid flag values as usage errors#106
sergiught merged 1 commit into
mainfrom
fix/flag-value-usage-errors

Conversation

@sergiught

Copy link
Copy Markdown
Owner

📝 Summary

Four flags accepted values they couldn't honour, and reported the problem late, badly, or not at all. All four now fail as usage errors (exit 2) before any request goes out.

--header was only parsed while constructing a client, so a reserved or malformed value surfaced as a runtime error (exit 1) with a run with -d/--debug for more detail hint — and commands that build no client accepted garbage silently. It's a bad invocation, so it's now validated in PersistentPreRunE alongside --jq and -o.

tuples changes --start-time promised RFC 3339 in its help but was passed to the server verbatim, so --start-time yesterday became a server-side rejection instead of a local usage error. Compare --consistency, which has always been checked locally against its enumerated values.

query list-users --typeMarkFlagRequired is satisfied by --type "", and --type 'org#' parsed into a filter with an empty relation. Both reached the server as degenerate filters and came back as a bare 400. (Validation also moved ahead of client construction, matching the sibling commands.)

--limit / --max-results are two flags bound to one variable across stores list, model list, tuples read and tuples changes, so passing both silently let whichever appeared last on the command line win. They now conflict explicitly.

🏷 Type of change

  • 🐛 Bug fix (non-breaking)
  • ✨ Feature (non-breaking)
  • 💥 Breaking change (users must update)
  • ♻️ Refactor (no functional change)
  • 📚 Docs only
  • 🛠 Build / CI / tooling

Each rejects an invocation that previously "worked" by silently doing something other than what was asked.

✅ How to verify

make check

New tests: TestBadHeaderIsAUsageError (drives the real binary through ofga version, which builds no client, so it only passes if the header is checked up front), TestListUsersRejectsDegenerateTypeFilters, TestRejectFlagAliasConflict, and TestParseTimestamp.

📋 Checklist

  • 🧪 Tests added or updated where it makes sense
  • 📖 Docs updated (README / command --help / examples) if behavior changed — help text already documented the expected formats; this enforces them
  • 🏷 PR title follows Conventional Commits
  • 🟢 make check passes locally

Four flags accepted values they could not honour, and said so late or not at
all.

--header was parsed only while building a client, so a reserved or malformed
value came back as a runtime error with a "run with --debug" hint, and
commands that build no client accepted it silently. It is now checked before
the command runs, like --jq and -o.

--start-time was sent to the server verbatim, so `--start-time yesterday`
became a server-side rejection rather than a usage error naming RFC 3339.

`list-users --type ""` satisfied MarkFlagRequired, and `--type 'org#'` built a
filter with an empty relation; both went out as degenerate filters and came
back as a bare 400.

--limit and --max-results write the same variable, so passing both silently
let whichever came last win. They now conflict explicitly.
@sergiught
sergiught merged commit b1e03c8 into main Aug 3, 2026
7 checks passed
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.

1 participant