{"record":{"id":"8b3217e500b6f2ba","repo":"LykosAI/StabilityMatrix","slug":"invalid-version-format-versionstring","errorCode":null,"errorMessage":"Invalid version format: {versionString}","messagePattern":"Invalid version format: (.+?)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"StabilityMatrix.Core/Python/PyVersion.cs","lineNumber":44,"sourceCode":"    /// <summary>\n    /// Creates a new PyVersion\n    /// </summary>\n    public PyVersion(int major, int minor, int micro)\n    {\n        Major = major;\n        Minor = minor;\n        Micro = micro;\n    }\n\n    /// <summary>\n    /// Parses a version string in the format \"major.minor.micro\"\n    /// </summary>\n    public static PyVersion Parse(string versionString)\n    {\n        var parts = versionString.Split('.');\n        if (parts.Length is < 2 or > 3)\n        {\n            throw new ArgumentException($\"Invalid version format: {versionString}\", nameof(versionString));\n        }\n\n        if (!int.TryParse(parts[0], out var major) || !int.TryParse(parts[1], out var minor))\n        {\n            throw new ArgumentException($\"Invalid version format: {versionString}\", nameof(versionString));\n        }\n\n        var micro = 0;\n        if (parts.Length <= 2)\n            return new PyVersion(major, minor, micro);\n\n        if (!int.TryParse(parts[2], out micro))\n        {\n            throw new ArgumentException($\"Invalid version format: {versionString}\", nameof(versionString));\n        }\n\n        return new PyVersion(major, minor, micro);\n    }","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/LykosAI/StabilityMatrix/blob/af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002/StabilityMatrix.Core/Python/PyVersion.cs#L26-L62","documentation":"PyVersion.Parse splits the version string on '.' and throws ArgumentException when it does not have 2–3 dot-separated parts. This is the strict parser used by TryParse, so it signals a malformed Python version string.","triggerScenarios":"PyVersion.Parse(\"3\") (only 1 part) or PyVersion.Parse(\"3.11.1.0\") (4 parts) — parts.Length < 2 or > 3.","commonSituations":"Parsing raw python executable output like 'Python 3.10.9' without trimming the prefix (resulting in 3 parts containing words, caught later); config entries like '3' for major-only; build strings like '3.11.9-rc1' handled elsewhere.","solutions":["Pass a 'major.minor' or 'major.minor.micro' string, e.g. \"3.11\" or \"3.11.9\".","Use PyVersion.TryParse when input may be malformed.","Strip non-numeric prefixes/suffixes (e.g. 'Python ', '-rc1') before parsing.","Normalize short forms like '3' to '3.0' before calling Parse."],"exampleFix":"// before\nvar v = PyVersion.Parse(versionString); // throws on \"3\"\n// after\nif (!PyVersion.TryParse(versionString, out var v)) { v = new PyVersion(3, 11, 0); }","handlingStrategy":"validation","validationCode":"bool IsPyVersionString(string s) =>\n    s.Split('.').Length is >= 2 and <= 3 &&\n    s.Split('.').All(p => p.All(char.IsDigit) && p.Length > 0);","typeGuard":"bool TryNormalizeVersion(string s, out string normalized) {\n    normalized = \"\";\n    var parts = s.Split('.');\n    if (parts.Length is < 2 or > 3) return false;\n    normalized = string.Join('.', parts);\n    return true;\n}","tryCatchPattern":"try { version = PyVersion.Parse(s); }\ncatch (ArgumentException) { version = PyVersion.Default; }","preventionTips":["Prefer TryParse for untrusted input","Normalize short forms ('3' -> '3.0') before parsing","Strip 'Python ' prefixes and pre-release suffixes first"],"tags":["python","version-parsing","argument-exception"],"backgroundTag":"invalid-argument-format","analyzedSha":"af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002","analyzedAt":"2026-09-12T19:02:43.389Z","contentChangedAt":"2026-09-12T19:02:43.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}