vectordotdev / vectordotdev/vector

vdev example-config generator emits invalid configs for mutually-exclusive-but-optional fields

Open
#26,175 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type: tech debt
Dominant language
Rust
Stars
22.6k
Forks
2.3k
Avg merge
1d 7h
Merged PRs (30d)
146

Description

Summary

The example-config generator emits a value for every field that has docs::examples metadata. It has no notion of "at most one of these fields", so for fields that are mutually exclusive but not required, it generates an example config that violates the component's own validation. The only existing mechanism, required_one_of, means "exactly one must be set" (it emits a JSON-Schema oneOf constraint and a docs note "Exactly one of X or Y must be set"). That is semantically wrong for fields where neither being set is valid.

Impact

  • check-generated-docs (which validates every generated example with vector validate --no-environment) fails on any sink whose mutually-exclusive fields both have examples.
  • Surfaced concretely by the axiom sink in #26171: url and region are mutually exclusive but neither is required. The auto-generated advanced.yaml set both, failing validation.
    • Workaround: url's docs::examples were removed so the generator only emits region. This keeps the example valid but degrades the docs: the url field no longer shows example values.

Proposed fix

  1. Deprecate the top-level flattened fields in favor of a non-flattened enum. The axiom sink's url/region are currently flattened into AxiomConfig as top-level fields. Deprecate them and introduce a single non-flattened endpoint field that is an enum (e.g. endpoint: { type: url, url: ... } | endpoint: { type: region, region: ... }). Mutual exclusivity becomes structural — an enum can only be one variant — so the example generator produces valid configs naturally, and the "at most one" problem disappears for this sink.

  2. If the above is not possible/feasible/doesn't make sense for all sinks: Add "at most one" support to the example generator (docs-only metadata, e.g. docs::exclusive / mutually_exclusive, distinct from required_one_of's "exactly one" semantics) so generated examples stay valid during the deprecation period and for any future mutually-exclusive-but-optional fields. The generator emits only one member of the group (reusing the existing group-selection logic in make_example_params), with no JSON-Schema oneOf constraint and no "exactly one required" docs note.

  3. After the deprecation window, remove the old top-level fields and the generator workaround, restoring full example values on the enum variants.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the example-config generator and its make_example_params group-selection logic; reproduce the failure through check-generated-docs or vector validate --no-environment using the axiom advanced.yaml case. Compare required_one_of with the desired optional-exclusivity semantics and assess the proposed endpoint/deprecation path. Done means generated examples validate while retaining endpoint examples.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
documentation, testing, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.