{"record":{"id":"62b4785637cd1da9","repo":"vectordotdev/vector","slug":"required-one-of-cannot-be-applied-to-a-serde","errorCode":null,"errorMessage":"`required_one_of` cannot be applied to a `#[serde(skip)]` field","messagePattern":"`required_one_of` cannot be applied to a `#\\[serde\\(skip\\)\\]` field","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"lib/vector-config-macros/src/configurable.rs","lineNumber":370,"sourceCode":"\n    quote! {\n        {\n            #field_schema\n            subschemas.push(subschema);\n        }\n    }\n}\n\nfn build_named_struct_generate_schema_fn(\n    container: &Container<'_>,\n    fields: &[Field<'_>],\n) -> proc_macro2::TokenStream {\n    // Validate required_one_of usage before building groups.\n    // Scan ALL fields (including non-visible) so #[serde(skip)] fields are caught too.\n    for field in fields.iter() {\n        if field.required_one_of().is_some() {\n            if !field.visible() {\n                return syn::Error::new(\n                    field.span(),\n                    \"`required_one_of` cannot be applied to a `#[serde(skip)]` field\",\n                )\n                .to_compile_error();\n            }\n            if field.flatten() {\n                return syn::Error::new(\n                    field.span(),\n                    \"`required_one_of` cannot be applied to a `#[serde(flatten)]` field\",\n                )\n                .to_compile_error();\n            }\n            if !is_option_type(field.ty())\n                && field.default_value().is_none()\n                && container.default_value().is_none()\n            {\n                return syn::Error::new(\n                    field.span(),","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/vectordotdev/vector/blob/3708c39b12a93212ed8b8d7510b4cc7769cb5864/lib/vector-config-macros/src/configurable.rs#L352-L388","documentation":"Compile-time error from `build_named_struct_generate_schema_fn` in vector-config-macros. Vector's `required_one_of` helper generates a schema-level `oneOf` requirement over serde field names, so every participating field must appear in the serialized/deserialized object. `#[serde(skip)]` removes the field from both, making the requirement unsatisfiable; the macro scans ALL fields (even non-visible ones) specifically to catch this.","triggerScenarios":"Applying both `#[serde(skip)]` and `#[configurable(required_one_of(...))]` to the same field of a `#[derive(Configurable)]` named struct.","commonSituations":"Refactoring a config struct where a field became internal (skip) but its old `required_one_of` attribute was left behind; merging configs where attributes accumulated.","solutions":["Remove the `#[configurable(required_one_of(...))]` attribute from the skipped field","Or remove `#[serde(skip)]` if the field is actually user-configurable and must be part of the group","Move the group membership to a visible field that carries the same semantic choice"],"exampleFix":"// before\n#[configurable(required_one_of = [\"strategy\"])]\n#[serde(skip)]\npub strategy_hint: Strategy,\n\n// after\n// (drop one of the two attributes; keep required_one_of only on deserialized fields)\npub strategy: Option<Strategy>,","handlingStrategy":"validation","validationCode":"# CI gate: attribute conflicts fail at compile time\ncargo check --workspace --all-targets","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Audit required_one_of members and remove the attribute when a field gains #[serde(skip)]","Remember the macro checks skipped fields too — conflicts always surface at compile time"],"tags":["rust","proc-macro","compile-time","serde","schema-validation","vector"],"backgroundTag":"macro-attribute-conflict","analyzedSha":"3708c39b12a93212ed8b8d7510b4cc7769cb5864","analyzedAt":"2026-08-20T07:02:18.786Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}