{"record":{"id":"f5a7f2632b7aa1b4","repo":"vectordotdev/vector","slug":"description-has-no-component-identifier","errorCode":null,"errorMessage":"{description} has no component identifier","messagePattern":"(.+?) has no component identifier","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vdev/src/commands/check/component_examples.rs","lineNumber":393,"sourceCode":"}\n\nfn yaml_mapping(value: &YamlValue, description: &str) -> Result<Mapping> {\n    value\n        .as_mapping()\n        .cloned()\n        .ok_or_else(|| anyhow!(\"Expected {description} to be a YAML mapping\"))\n}\n\nfn mapping_value<'a>(mapping: &'a Mapping, key: &str) -> Option<&'a YamlValue> {\n    mapping.get(YamlValue::String(key.to_owned()))\n}\n\nfn mapping_key(mapping: &Mapping, description: &str) -> Result<String> {\n    mapping\n        .keys()\n        .find_map(YamlValue::as_str)\n        .map(str::to_owned)\n        .ok_or_else(|| anyhow!(\"{description} has no component identifier\"))\n}\n\nfn vector_binary(repo_root: &Path) -> Result<PathBuf> {\n    if let Some(vector_bin) = std::env::var_os(\"VECTOR_BIN\") {\n        return Ok(PathBuf::from(vector_bin));\n    }\n\n    let status = Command::new(\"cargo\")\n        .current_dir(repo_root)\n        .args([\"build\", \"--bin\", \"vector\"])\n        .status()\n        .context(\"Failed to build Vector for example validation\")?;\n    if !status.success() {\n        bail!(\"Failed to build Vector for example validation\")\n    }\n\n    let target_dir = std::env::var_os(\"CARGO_TARGET_DIR\").map_or_else(\n        || repo_root.join(\"target\"),","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/vdev/src/commands/check/component_examples.rs#L375-L411","documentation":"`mapping_key` extracts the single string key identifying the component within a `sources`/`transforms`/`sinks` mapping. If the mapping has no string keys (empty mapping, or keys that are numbers/booleans/null), it cannot determine the component identifier and throws this error.","triggerScenarios":"The component section mapping contains no entries, or its keys are non-string YAML scalars (e.g. unquoted numeric keys like `2024:`), which `YamlValue::as_str` rejects.","commonSituations":"An example file with an empty placeholder section was committed; YAML parsed an unquoted numeric key as an integer; merge conflicts left an empty mapping behind.","solutions":["Add exactly one string-keyed entry to the component section naming the component.","Quote numeric-looking keys (e.g. `\"my_source\":`) so they parse as strings.","Resolve leftover merge-conflict or empty-section placeholders before running the check."],"exampleFix":"// before\nsources:\n  2024_config:\n    type: file\n\n// after\nsources:\n  my_source:\n    type: file","handlingStrategy":"validation","validationCode":"const stringKeys = Object.keys(mapping).filter(k => typeof k === 'string');\nif (stringKeys.length < 1) {\n  throw new Error(`${description} must contain at least one string component key`);\n}","typeGuard":"function hasStringKey(mapping) {\n  return Object.keys(mapping ?? {}).some(k => typeof k === 'string' && k.length > 0);\n}","tryCatchPattern":null,"preventionTips":["Quote numeric-looking keys in YAML so they parse as strings.","Resolve merge conflicts fully; don't leave empty mappings."],"tags":["yaml","config-validation","vector"],"backgroundTag":"missing-required-config-field","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"}