{"record":{"id":"7237c8bfc3bc6aac","repo":"FuelLabs/sway","slug":"invalid-version-requirement-v","errorCode":null,"errorMessage":"invalid version requirement `{v}`","messagePattern":"invalid version requirement `(.+?)`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"forc-pkg/src/manifest/dep_modifier.rs","lineNumber":259,"sourceCode":"impl FromStr for DepSpec {\n    type Err = anyhow::Error;\n\n    fn from_str(s: &str) -> anyhow::Result<Self> {\n        if s.trim().is_empty() {\n            bail!(\"Dependency spec cannot be empty\");\n        }\n\n        let mut s = s.trim().split('@');\n\n        let name = s\n            .next()\n            .ok_or_else(|| anyhow::anyhow!(\"missing dependency name\"))?;\n\n        let version_req = s.next().map(|s| s.to_string());\n\n        if let Some(ref v) = version_req {\n            semver::VersionReq::parse(v)\n                .map_err(|_| anyhow::anyhow!(\"invalid version requirement `{v}`\"))?;\n        }\n\n        Ok(Self {\n            name: name.to_string(),\n            version_req,\n        })\n    }\n}\n\nimpl fmt::Display for DepSpec {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match &self.version_req {\n            Some(version) => write!(f, \"{}@{}\", self.name, version),\n            None => write!(f, \"{}\", self.name),\n        }\n    }\n}\n","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/FuelLabs/sway/blob/47e5e902faa42baf652dd6a0c88cd23390c1a614/forc-pkg/src/manifest/dep_modifier.rs#L241-L277","documentation":"When a forc add spec contains '@', the part after it is parsed with semver::VersionReq::parse - the cargo-style requirement grammar ('1.2.3', '^1.2', '>=0.5, <0.9'). This error echoes the exact string that failed to parse. Version tags with 'v' prefixes, branch names, or words like 'latest' are not semver requirements and are rejected here.","triggerScenarios":"forc add pkg@latest, pkg@v1.0.0, pkg@main, or any post-@ string that is not a valid semver requirement range.","commonSituations":"Habits carried from npm ('latest') or git tags ('v1.0.0'); wanting to depend on a branch or commit instead of a version; typos like '1..2'.","solutions":["Use a valid semver requirement: forc add pkg@1.2.3, pkg@^1.2.0, or pkg@>=0.5,<0.9.","To depend on a git branch, tag or commit, edit Forc.toml's [dependencies] with git = ..., and branch = .../tag = ... keys rather than a version spec.","Validate the requirement string against the semver spec (semver.org) or with cargo's own parser before scripting many adds."],"exampleFix":"# before\n$ forc add mydep@v1.2.3\n\n# after\n$ forc add mydep@1.2.3\n\n# or pin a git tag in Forc.toml\n[dependencies]\nmydep = { git = \"https://github.com/org/mydep\", tag = \"v1.2.3\" }","handlingStrategy":"validation","validationCode":"// Rust, validate the version-req half before calling DepSpec::from_str / forc add:\nfn valid_version_req(spec: &str) -> bool {\n    match spec.trim().split_once('@') {\n        Some((_, v)) => semver::VersionReq::parse(v).is_ok(),\n        None => true, // no version part is fine\n    }\n}","typeGuard":null,"tryCatchPattern":"// anyhow Result - convert to an actionable message:\nmatch DepSpec::from_str(\"pkg@latest\") {\n    Err(e) if e.to_string().contains(\"invalid version requirement\") =>\n        eprintln!(\"use a semver requirement like ^1.2.0, or a git/branch entry in Forc.toml\"),\n    other => other.unwrap(),\n}","preventionTips":["Use cargo-style semver requirements after @ (^1.2.0, >=0.5,<0.9, 1.2.3).","Never use 'latest', 'v'-prefixed tags, or branch names as version requirements.","Put branch/tag/commit dependencies in Forc.toml with git keys instead.","For git-tag pins like v1.2.3, declare tag = \"v1.2.3\" rather than @v1.2.3."],"tags":["forc","cli","semver","dependency"],"backgroundTag":null,"analyzedSha":"47e5e902faa42baf652dd6a0c88cd23390c1a614","analyzedAt":"2026-08-16T07:57:45.555Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}