{"record":{"id":"ea3427736277c6d2","repo":"dbt-labs/dbt-core","slug":"expected-lane-n-after-got-pre-in-sem","errorCode":null,"errorMessage":"expected `<lane>.N` after `-`, got {pre:?} in {semver:?}","messagePattern":"expected `<lane>\\.N` after `-`, got (.+?) in (.+?)","errorType":"validation","errorClass":"anyhow","httpStatus":null,"severity":"error","filePath":"crates/dbt-ci/src/release_version.rs","lineNumber":69,"sourceCode":"        None => (semver, None),\n    };\n    let parts: Vec<&str> = base.split('.').collect();\n    let well_formed = parts.len() == 3\n        && parts\n            .iter()\n            .all(|p| !p.is_empty() && p.chars().all(|c| c.is_ascii_digit()));\n    if !well_formed {\n        bail!(\"expected X.Y.Z, got {base:?} in {semver:?}\");\n    }\n    let Some(pre) = pre else {\n        return Ok(ParsedReleaseVersion {\n            base,\n            prerelease: None,\n        });\n    };\n    let (lane_str, number) = pre\n        .split_once('.')\n        .ok_or_else(|| anyhow!(\"expected `<lane>.N` after `-`, got {pre:?} in {semver:?}\"))?;\n    let lane = PreReleaseLane::parse(lane_str).ok_or_else(|| {\n        anyhow!(\n            \"unsupported pre-release lane {lane_str:?} in {semver:?}; \\\n             accepted: alpha, beta, rc, preview, dev\"\n        )\n    })?;\n    if number.is_empty() || !number.chars().all(|c| c.is_ascii_digit()) {\n        bail!(\"expected integer after `{lane_str}.`, got {number:?} in {semver:?}\");\n    }\n    Ok(ParsedReleaseVersion {\n        base,\n        prerelease: Some((lane, number)),\n    })\n}\n\npub(crate) fn validate_release_version(semver: &str) -> Result<()> {\n    parse_release_version(semver).map(|_| ())\n}","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-ci/src/release_version.rs#L51-L87","documentation":"parse_release_version validates semver pre-release suffixes: after the `-`, the identifier must be `<lane>.N` where lane is one of alpha, beta, rc, preview, dev. This error fires when the pre-release string contains no dot, so no lane/number pair can be split. It guards conversion of semver versions to PEP 440 for PyPI publishing.","triggerScenarios":"Calling parse_release_version (directly or via run, validate_release_version, or semver_to_pep440) with a version whose pre-release part after `-` lacks a `.N` suffix, e.g. `1.2.3-beta` or `1.2.3-rc`.","commonSituations":"Tagging releases as `v1.2.3-rc` from habit with other tooling; reading a version from git tags or env vars produced by scripts that drop the numeric component; mismatch between semver tooling that allows bare pre-release ids and this stricter lane format.","solutions":["Change the version to the `<lane>.N` form, e.g. `1.2.3-beta` becomes `1.2.3-beta.0` or `1.2.3-rc.1`.","Use only supported lanes: alpha, beta, rc, preview, dev.","If the version comes from a script or git tag, update the generator to always append `.N` after the lane."],"exampleFix":"// before\nlet v = parse_release_version(\"1.2.3-beta\")?;\n\n// after\nlet v = parse_release_version(\"1.2.3-beta.0\")?;","handlingStrategy":"validation","validationCode":"import re\nSEMVER_LANE = re.compile(r'^\\d+\\.\\d+\\.\\d+-(alpha|beta|rc|preview|dev)\\.\\d+$')\nassert SEMVER_LANE.match(version), f\"{version} must be <major>.<minor>.<patch>-<lane>.N\"","typeGuard":"def is_lane_version(v: str) -> bool:\n    import re\n    return bool(re.match(r'^\\d+\\.\\d+\\.\\d+-(alpha|beta|rc|preview|dev)\\.\\d+$', v))","tryCatchPattern":"match parse_release_version(&version) {\n    Err(e) if e.to_string().contains(\"`<lane>.N`\") => bail!(\"use -alpha.0 style pre-release: {version}\"),\n    other => other,\n}","preventionTips":["Standardize release tags on the <lane>.N format in your release script","Validate git tags with a CI regex before invoking release tooling","Document accepted lanes (alpha, beta, rc, preview, dev) for the team"],"tags":["versioning","semver","parsing","release"],"backgroundTag":"invalid-argument-format","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}