Summary
--config / --config-file and the individual destination config flags should be mutually exclusive on gateway destination create, update and upsert. This is a breaking change, so it belongs in 3.0.0 — it was implemented during #392 and then deliberately reverted out of the 2.6.0 release.
The problem today
--config is documented as supplying the whole config, and individual flags are documented as overriding it. Neither is quite true. What actually happens:
- Two fields win.
--url on create, and --url on upsert only when --type is also supplied, overlay the JSON.
- About ten are silently discarded.
--auth-method, --bearer-token, --basic-auth-user/pass, --api-key, --custom-signature-*, --http-method, --path-forwarding-disabled, --rate-limit, --rate-limit-period and every --delivery-group-* flag are dropped without a word when --config is present.
- The three commands disagree.
create has an overlay; upsert has one that only fires with --type; update has none. So upsert --config '{"url":"https://old"}' --url https://new --type HTTP sends the new URL while the same flags on update send the old one.
Silent discard is the failure shape most of #392 was about: the command reports success while ignoring what you asked for.
Why mutual exclusion rather than "the flag always wins"
Making every flag win means answering merge questions nobody has asked — what should happen to delivery_policy.groups when --config sets it and --delivery-group-overrides is supplied? Which wins per nested key?
It would also cost an API lookup: the current resolveDestinationType deliberately returns early when --config is in play, so making --url win on that path means fetching the stored destination just to learn which field name to overlay.
Refusal closes every corner with one rule, needs no lookup, and makes the three commands agree.
Why it is breaking, and therefore 3.0.0
Verified against the pre-change build:
destination create --type HTTP --config '{"url":"https://from-config"}' --url https://from-flag
# before: succeeds, sends url=https://from-flag
# after: error — --url cannot be combined with --config
Anyone scripting --config for the bulk of a destination plus --url for the part that varies gets an error where they previously got a working command. Rare, but real.
Implementation notes from the reverted work
The reverted implementation is recoverable from faa742f on fix/rc-exercise-findings (the revert commit follows it). It:
- added
rejectConfigJSONWithIndividualFlags in pkg/cmd/destination_common.go, called from validateFlags on all three commands;
- keyed off pflag's
Changed, so --api-key-to's header default and create's --cli-path / default are not treated as conflicts — this matters, a naive emptiness check produces false conflicts;
- removed two overlays that become unreachable (
destination_upsert.go, and the --url half in destination_create.go — its applyCLIPath call must stay, since the / default still applies on the --config path);
- came with
TestDestinationConfigJSONRefusesIndividualFlags (7 flags × 3 commands), TestDestinationConfigFileRefusesIndividualFlagsToo, TestDestinationConfigJSONAloneIsStillAccepted (defaults must not trip it) and TestDestinationUpsertAndUpdateAgreeOnConfigJSON.
Error text used: --url cannot be combined with --config: --config supplies the whole config, so put the field in the JSON or drop --config.
Until then
2.6.0 ships the existing behaviour: two fields overlay, the rest are silently dropped, and the three commands disagree. Worth a --help note if this sits for a while.
Related
Filed by Claude on Phil's behalf. Reverted from 2.6.0 per the rule that breaking changes ship in a major release.
Summary
--config/--config-fileand the individual destination config flags should be mutually exclusive ongateway destination create,updateandupsert. This is a breaking change, so it belongs in 3.0.0 — it was implemented during #392 and then deliberately reverted out of the 2.6.0 release.The problem today
--configis documented as supplying the whole config, and individual flags are documented as overriding it. Neither is quite true. What actually happens:--urloncreate, and--urlonupsertonly when--typeis also supplied, overlay the JSON.--auth-method,--bearer-token,--basic-auth-user/pass,--api-key,--custom-signature-*,--http-method,--path-forwarding-disabled,--rate-limit,--rate-limit-periodand every--delivery-group-*flag are dropped without a word when--configis present.createhas an overlay;upserthas one that only fires with--type;updatehas none. Soupsert --config '{"url":"https://old"}' --url https://new --type HTTPsends the new URL while the same flags onupdatesend the old one.Silent discard is the failure shape most of #392 was about: the command reports success while ignoring what you asked for.
Why mutual exclusion rather than "the flag always wins"
Making every flag win means answering merge questions nobody has asked — what should happen to
delivery_policy.groupswhen--configsets it and--delivery-group-overridesis supplied? Which wins per nested key?It would also cost an API lookup: the current
resolveDestinationTypedeliberately returns early when--configis in play, so making--urlwin on that path means fetching the stored destination just to learn which field name to overlay.Refusal closes every corner with one rule, needs no lookup, and makes the three commands agree.
Why it is breaking, and therefore 3.0.0
Verified against the pre-change build:
Anyone scripting
--configfor the bulk of a destination plus--urlfor the part that varies gets an error where they previously got a working command. Rare, but real.Implementation notes from the reverted work
The reverted implementation is recoverable from
faa742fonfix/rc-exercise-findings(the revert commit follows it). It:rejectConfigJSONWithIndividualFlagsinpkg/cmd/destination_common.go, called fromvalidateFlagson all three commands;Changed, so--api-key-to'sheaderdefault andcreate's--cli-path/default are not treated as conflicts — this matters, a naive emptiness check produces false conflicts;destination_upsert.go, and the--urlhalf indestination_create.go— itsapplyCLIPathcall must stay, since the/default still applies on the--configpath);TestDestinationConfigJSONRefusesIndividualFlags(7 flags × 3 commands),TestDestinationConfigFileRefusesIndividualFlagsToo,TestDestinationConfigJSONAloneIsStillAccepted(defaults must not trip it) andTestDestinationUpsertAndUpdateAgreeOnConfigJSON.Error text used:
--url cannot be combined with --config: --config supplies the whole config, so put the field in the JSON or drop --config.Until then
2.6.0 ships the existing behaviour: two fields overlay, the rest are silently dropped, and the three commands disagree. Worth a
--helpnote if this sits for a while.Related
--configmeans two different things across gateway and outpostdestination updatesilently dropping--urlwhen--typeis omitted (the same shape, fixed in 2.6.0 for the non---configpath)Filed by Claude on Phil's behalf. Reverted from 2.6.0 per the rule that breaking changes ship in a major release.