{"record":{"id":"1c45fd603d959ef4","repo":"microsoft/aspire","slug":"unsupported-aspire-skills-bundle-version-comparator-0","errorCode":null,"errorMessage":"Unsupported Aspire skills bundle version comparator '{0}'.","messagePattern":"Unsupported Aspire skills bundle version comparator '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/Agents/AspireSkills/AspireSkillsBundleProvider.cs","lineNumber":696,"sourceCode":"        }\n\n        return true;\n    }\n\n    private static bool SatisfiesComparator(SemVersion version, string comparator)\n    {\n        var (op, operandText) = ParseComparator(comparator);\n        var operand = ParseCompatibilityVersion(operandText);\n        var comparison = SemVersion.ComparePrecedence(version, operand);\n\n        return op switch\n        {\n            \">\" => comparison > 0,\n            \">=\" => comparison >= 0,\n            \"<\" => comparison < 0,\n            \"<=\" => comparison <= 0,\n            \"=\" or \"==\" => comparison == 0,\n            _ => throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, \"Unsupported Aspire skills bundle version comparator '{0}'.\", op))\n        };\n    }\n\n    private static (string Operator, string Operand) ParseComparator(string comparator)\n    {\n        foreach (var op in new[] { \">=\", \"<=\", \"==\", \">\", \"<\", \"=\" })\n        {\n            if (comparator.StartsWith(op, StringComparison.Ordinal))\n            {\n                var operand = comparator[op.Length..];\n                if (string.IsNullOrWhiteSpace(operand))\n                {\n                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, \"Aspire skills bundle contains an invalid version comparator '{0}'.\", comparator));\n                }\n\n                return (op, operand);\n            }\n        }","sourceCodeStart":678,"sourceCodeEnd":714,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/Agents/AspireSkills/AspireSkillsBundleProvider.cs#L678-L714","documentation":"Each comparator token in a version range must use one of the supported operators >, >=, <, <=, = or == (or the wildcards *, x, X). After parsing, any comparator with an unrecognized operator causes this formatted InvalidOperationException.","triggerScenarios":"A range token such as \"~9.0.0\", \"^9\", \"!=1.0.0\", or \"9.0.0-alpha\"-style bare token without a recognized operator reaches the switch in IsVersionInRange.","commonSituations":"Authors using npm/semver-style caret or tilde ranges ('^9.0.0', '~9.0') that this parser does not implement, or typos like '=>' or '>>'.","solutions":["Rewrite caret/tilde ranges into supported comparators, e.g. '^9.0.0' becomes '>=9.0.0 <10.0.0'","Use only >, >=, <, <=, =, == operators (and *, x, X wildcards) in supports ranges","Republish the bundle with the corrected range"],"exampleFix":"// before\n\"supports\": { \"aspireCli\": \"^9.4.0\" }\n// after\n\"supports\": { \"aspireCli\": \">=9.4.0 <10.0.0\" }","handlingStrategy":"validation","validationCode":"var supportedOps = new[] { \">=\", \"<=\", \"==\", \">\", \"<\", \"=\", \"*\", \"x\", \"X\" };\nforeach (var token in range.Split(' ', ','))\n    if (token.Length > 0 && !supportedOps.Any(op => token.StartsWith(op)))\n        throw new InvalidOperationException($\"Unsupported comparator '{token}'; use >, >=, <, <=, =, ==.\");","typeGuard":null,"tryCatchPattern":"try\n{\n    await installer.InstallAsync(bundleRef);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Unsupported Aspire skills bundle version comparator\"))\n{\n    logger.LogError(ex, \"Range uses an unsupported operator (e.g. '^' or '~'); rewrite with supported comparators.\");\n}","preventionTips":["Do not use npm semver caret/tilde syntax in Aspire bundle ranges","Convert '^9.4.0' to '>=9.4.0 <10.0.0' in authoring templates","Add a range syntax test to bundle CI"],"tags":["cli","skills-bundle","version-range","invalid-syntax"],"backgroundTag":"invalid-argument-format","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}