cross-rs/cross · error
invalid header section, got
Error message
invalid header section, got {s} What it means
ChangelogType::from_header converts a '### ' markdown header in a changelog into a ChangelogType enum. Only Added, Changed, Fixed, Removed and Internal are recognized; any other section title causes this bail. It enforces a fixed changelog section vocabulary for release note generation.
Solutions
- Rename the header to one of the supported sections: Added, Changed, Fixed, Removed, Internal
- Fix typos or casing in the changelog header (matching is exact)
- If a new section is genuinely needed, add a ChangelogType variant and from_header arm plus a sort_by entry
Example fix
// before ### Security - bumped dependency // after ### Fixed - bumped dependency (security fix)
Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED: [&str; 5] = ["Added", "Changed", "Fixed", "Removed", "Internal"];
assert!(ALLOWED.contains(&header), "unsupported changelog section: {header}"); Type guard
fn is_valid_section(header: &str) -> bool {
matches!(header, "Added" | "Changed" | "Fixed" | "Removed" | "Internal")
} Try / catch
match ChangelogType::from_header(header) {
Ok(t) => kind = Some(t),
Err(e) => eprintln!("skipping unsupported section {header:?}: {e}"),
} Prevention
- Restrict changelog sections to the five supported headings via a lint/CI check
- Copy sections from an existing release rather than the upstream Keep-a-Changelog template
- Fix casing exactly — matching is case-sensitive
When it happens
Trigger: read_changelog encounters a line like '### Security' or '### Deprecated' (or a misspelled/translated section name) and passes the header text to from_header.
Common situations: Contributors add a new section to CHANGELOG.md following common Keep-a-Changelog conventions (Security, Deprecated) that this project does not support; typos like '### Fixeds'; localized section names.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
AI-assisted analysis of cross-rs/cross@8c1a8aa4b6 (2026-09-13).
Data as JSON: /api/errors/b80b389b2cf1348e.
Report an issue: GitHub.
Appendix: source
Thrown at xtask/src/changelog.rs:127
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
enum ChangelogType {
Added,
Changed,
Fixed,
Removed,
Internal,
}
impl ChangelogType {
fn from_header(s: &str) -> cross::Result<Self> {
Ok(match s {
"Added" => Self::Added,
"Changed" => Self::Changed,
"Fixed" => Self::Fixed,
"Removed" => Self::Removed,
"Internal" => Self::Internal,
_ => eyre::bail!("invalid header section, got {s}"),
})
}
fn sort_by(&self) -> u32 {
match self {
ChangelogType::Added => 4,
ChangelogType::Changed => 3,
ChangelogType::Fixed => 2,
ChangelogType::Removed => 1,
ChangelogType::Internal => 0,
}
}
}
impl cmp::PartialOrd for ChangelogType {
fn partial_cmp(&self, other: &ChangelogType) -> Option<cmp::Ordering> {
Some(self.cmp(other))
}View on GitHub (pinned to 8c1a8aa4b6)