{"record":{"id":"9d423079104aa244","repo":"vectordotdev/vector","slug":"invalid-fragment-path-fragments-must-live-directly-under","errorCode":null,"errorMessage":"invalid fragment path '{}': fragments must live directly under {CHANGELOG_DIR}/, not in a subdirectory.","messagePattern":"invalid fragment path '(.+?)': fragments must live directly under (.+?)/, not in a subdirectory\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vdev/src/commands/check/changelog_fragments.rs","lineNumber":77,"sourceCode":"            bail!(\n                \"Too many changelog fragments ({} > {}).\",\n                added_real.len(),\n                self.max_fragments\n            );\n        }\n\n        // Every touched fragment (added or modified) must pass the schema check.\n        let modified: Vec<PathBuf> = diff_fragments(&self.merge_base, \"M\")?\n            .into_iter()\n            .filter(is_real_fragment)\n            .collect();\n        let expected_parent = std::path::Path::new(CHANGELOG_DIR);\n        for path in added_real.iter().chain(modified.iter()) {\n            let Some(name) = path.file_name().and_then(|s| s.to_str()) else {\n                bail!(\"Unexpected fragment path: {}\", path.display());\n            };\n            if path.parent() != Some(expected_parent) {\n                bail!(\n                    \"invalid fragment path '{}': fragments must live directly under {CHANGELOG_DIR}/, not in a subdirectory.\",\n                    path.display()\n                );\n            }\n            info!(\"Validating '{name}'\");\n            let fragment_type = validate_filename(name)?;\n            validate_contents(&repo_root.join(path), name, fragment_type)?;\n        }\n\n        // Cross-fragment check: derived-or-explicit anchors across every breaking fragment\n        // currently in `changelog.d/` must be unique and non-empty. Catches conflicts at CI\n        // time rather than at release time (when a partial CUE may already exist).\n        validate_breaking_anchor_set(&changelog_dir)?;\n\n        info!(\"changelog additions are valid.\");\n        Ok(())\n    }\n}","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/vdev/src/commands/check/changelog_fragments.rs#L59-L95","documentation":"Fragments must live directly under changelog.d/, not in subdirectories. For each added/modified fragment the checker compares the path's parent against changelog.d and bails if they differ, because filename validation and release tooling only expect top-level fragments.","triggerScenarios":"Adding a fragment in a nested path such as changelog.d/subdir/my_fix.md (or a path whose normalized parent differs from CHANGELOG_DIR) and running the check.","commonSituations":"Creating fragments inside feature subfolders for organization; scripts writing to changelog.d/<category>/; an editor creating the file in the wrong directory.","solutions":["Move the fragment to the top level: `git mv changelog.d/subdir/my_fix.md changelog.d/my_fix.md`","Re-create it at the top level with `vdev changelog new <type> <slug>`","Fix any script that writes fragments into subdirectories of changelog.d/"],"exampleFix":"# before\nchangelog.d/bugs/my_fix.md\n# after\ngit mv changelog.d/bugs/my_fix.md changelog.d/my_fix.md","handlingStrategy":"validation","validationCode":"if (path.dirname(fragmentPath) !== \"changelog.d\") throw new Error(\"fragments must be directly under changelog.d/\");","typeGuard":"const isTopLevelFragment = (p) => path.posix.dirname(p.replace(/\\\\/g, \"/\")) === \"changelog.d\";","tryCatchPattern":"try { runCheck(); } catch (e) { if (/must live directly under/.test(e.message)) { gitMvToTopLevel(parsePath(e.message)); } throw e; }","preventionTips":["Always create fragments at changelog.d/ top level","Configure editors/templates to write to changelog.d/, not subfolders","Lint generated fragments' paths in CI before running the checker"],"tags":["filesystem","changelog","validation"],"backgroundTag":"invalid-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"}