{"record":{"id":"a91920eae66f063b","repo":"vectordotdev/vector","slug":"unsupported-dynamic-feature-selector","errorCode":null,"errorMessage":"UNSUPPORTED_DYNAMIC_FEATURE_SELECTOR","messagePattern":"UNSUPPORTED_DYNAMIC_FEATURE_SELECTOR","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vdev/src/utils/features.rs","lineNumber":168,"sourceCode":"    }\n}\n\nfn from_config(config: &FeatureConfig, declared_features: &FeatureSet) -> Result<Vec<String>> {\n    if config.provider.is_some() {\n        bail!(UNSUPPORTED_PROVIDER);\n    }\n    if [\n        &config.enrichment_tables,\n        &config.secret,\n        &config.sources,\n        &config.transforms,\n        &config.sinks,\n    ]\n    .into_iter()\n    .flat_map(|section| section.values())\n    .any(|component| has_dynamic_reference(&component.r#type))\n    {\n        bail!(UNSUPPORTED_DYNAMIC_FEATURE_SELECTOR);\n    }\n    let mut features = FeatureSet::default();\n    add_option(&mut features, \"api\", config.api.as_ref());\n\n    get_features(\n        &mut features,\n        \"enrichment-tables\",\n        &config.enrichment_tables,\n        declared_features,\n    );\n    get_features(&mut features, \"secrets\", &config.secret, declared_features);\n    get_features(&mut features, \"sources\", &config.sources, declared_features);\n    get_features(\n        &mut features,\n        \"transforms\",\n        &config.transforms,\n        declared_features,\n    );","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/vdev/src/utils/features.rs#L150-L186","documentation":"from_config scans the `type` field of every component under enrichment_tables, secret, sources, transforms, and sinks; if any type string contains a dynamic reference (template/condition syntax rather than a literal component type), it bails with UNSUPPORTED_DYNAMIC_FEATURE_SELECTOR. Static analysis of the config cannot map a dynamic type to concrete cargo features.","triggerScenarios":"Calling load_and_extract where a component's `type` uses dynamic interpolation or a conditional expression (has_dynamic_reference match) instead of a fixed string like \"console\".","commonSituations":"Programmatically generated configs with templated component types; hand-written configs that accidentally left a placeholder (e.g. \"${SINK_TYPE}\") in a type field.","solutions":["Replace the dynamic type expression with the literal component type string","Pre-render the templated config to a static one before running feature extraction","Split the config so each component has a concrete, static `type`"],"exampleFix":"// before\nsinks:\n  out:\n    type: ${SINK_TYPE}\n// after\nsinks:\n  out:\n    type: console","handlingStrategy":"validation","validationCode":"fn is_static_type(cfg: &serde_yaml::Value) -> bool {\n    cfg.get(\"sinks\").map(|s| s.as_mapping().map(|m| m.values().all(|c|\n        c.get(\"type\").and_then(|t| t.as_str()).map(|ts| !ts.contains(\"${\") && !ts.contains(\"{{\")).unwrap_or(false)\n    )).unwrap_or(false)).unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always write component `type` fields as literal strings","Render templates to static configs before static analysis","Add a lint that flags `${`/`{{` inside any component type field"],"tags":["rust","config","validation","template"],"backgroundTag":"unsupported-config-value","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}