{"record":{"id":"0dcc0fc914a3d0f0","repo":"vectordotdev/vector","slug":"version-s-has-prerelease-or-build-metadata-only-plain-x-y-z","errorCode":null,"errorMessage":"version '{s}' has prerelease or build metadata; only plain X.Y.Z is allowed","messagePattern":"version '(.+?)' has prerelease or build metadata; only plain X\\.Y\\.Z is allowed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vdev/src/utils/deprecation.rs","lineNumber":409,"sourceCode":"            );\n        }\n    }\n    Ok(enacted.len())\n}\n\n/// True when `a` is in a later major.minor release than `b`. Equal or smaller\n/// major.minor (regardless of patch) returns false.\npub fn later_minor(a: &Version, b: &Version) -> bool {\n    (a.major, a.minor) > (b.major, b.minor)\n}\n\n/// Parse a release version string strictly: only plain `X.Y.Z` is allowed\n/// (no prerelease or build metadata). Mirrors the rule that release tags\n/// follow `vX.Y.Z`.\npub fn parse_strict_release(s: &str) -> Result<Version> {\n    let v = Version::parse(s)?;\n    if !v.pre.is_empty() || !v.build.is_empty() {\n        bail!(\"version '{s}' has prerelease or build metadata; only plain X.Y.Z is allowed\");\n    }\n    Ok(v)\n}\n\n/// Render the JSON that `sync_deprecations_cue` would write, without\n/// touching disk. Returns the serialized string (with trailing newline) so\n/// callers can compare against the on-disk file.\npub fn rendered_json(repo_root: &Path) -> Result<String> {\n    let dir = repo_root.join(DEPRECATION_DIR);\n    let pending = read_deprecation_fragments(&dir)?;\n    let mut data = read_json(repo_root)?;\n    sort_enacted(&mut data.deprecations_enacted);\n    data.deprecations_pending = pending_excluding_enacted(&pending, &data.deprecations_enacted);\n    Ok(serde_json::to_string_pretty(&data)? + \"\\n\")\n}\n\n/// Regenerate `DEPRECATIONS_JSON` from `deprecation.d/` (pending) plus the\n/// existing enacted entries already in the file.","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/vdev/src/utils/deprecation.rs#L391-L427","documentation":"parse_strict_release parses a version string with semver::Version::parse but additionally rejects versions carrying prerelease (e.g. -alpha.1) or build metadata (e.g. +build.5). This mirrors the repository's release-tag convention of plain `vX.Y.Z` tags, so any non-plain version is treated as invalid input for release-based validation and sorting.","triggerScenarios":"Calling parse_strict_release (directly or via sort_enacted/validate_enacted) with strings like \"0.45.0-rc.1\", \"1.2.3+build\", or any X.Y.Z-suffix form instead of a bare \"X.Y.Z\".","commonSituations":"A deprecation entry referencing a release candidate or nightly build as its removed_in/deprecated_since version; copy-pasting a version from Cargo/semver output that included build metadata; typo-ed version strings pulled from non-release tags.","solutions":["Change the version string to a plain three-component release, e.g. \"0.45.0-rc.1\" → \"0.45.0\"","Drop build metadata (everything from `+` onward) and any `-prerelease` suffix","If a prerelease genuinely must be referenced, use the eventual final release version it shipped in"],"exampleFix":"// before\nlet v = parse_strict_release(\"0.45.0-rc.1\")?;\n// after\nlet v = parse_strict_release(\"0.45.0\")?;","handlingStrategy":"validation","validationCode":"fn is_plain_release(s: &str) -> bool {\n    semver::Version::parse(s).map(|v| v.pre.is_empty() && v.build.is_empty()).unwrap_or(false)\n}\nassert!(is_plain_release(\"0.45.0\"));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Copy versions from actual `vX.Y.Z` release tags, not Cargo prerelease output","Strip `-suffix` and `+metadata` before storing a version in deprecation metadata","Lint deprecation files for prerelease/build-metadata patterns in CI"],"tags":["rust","semver","validation","version-format"],"backgroundTag":"invalid-date-format","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"}