{"record":{"id":"a1e1bcad9f952e51","repo":"Humanizr/Humanizer","slug":"unsupported-harmony-ordinal-suffix-strategy","errorCode":null,"errorMessage":"Unsupported harmony-ordinal suffix strategy.","messagePattern":"Unsupported harmony-ordinal suffix strategy\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Humanizer/Localisation/NumberToWords/HarmonyOrdinalNumberToWordsConverter.cs","lineNumber":148,"sourceCode":"        value >= 0 ? (ulong)value : unchecked((ulong)(-(value + 1)) + 1);\n\n    /// <summary>\n    /// Converts the given value using the locale's harmony-based ordinal rules.\n    /// </summary>\n    /// <param name=\"number\">The number to convert.</param>\n    /// <returns>The localized ordinal words for <paramref name=\"number\"/>.</returns>\n    public override string ConvertToOrdinal(int number)\n    {\n        // Ordinals are the cardinal form plus a suffix strategy chosen by the generated profile.\n        var word = Convert(number);\n        return profile.OrdinalSuffixStrategy switch\n        {\n            HarmonyOrdinalSuffixStrategy.LastVowelMap => AppendHarmonySuffix(word, profile.OrdinalSuffixes, useTerminalVowelOrdinalSuffixes: true),\n            HarmonyOrdinalSuffixStrategy.FinalCharacterMembership => AppendMembershipOrdinalSuffix(\n                word,\n                profile.SecondOrdinalSuffixCharacters,\n                profile.OrdinalSuffixPair),\n            _ => throw new InvalidOperationException(\"Unsupported harmony-ordinal suffix strategy.\")\n        };\n    }\n\n    /// <summary>\n    /// Converts the given value to a tuple form, using either a named tuple or harmony suffixes.\n    /// </summary>\n    /// <param name=\"number\">The number to convert.</param>\n    /// <returns>The localized tuple words for <paramref name=\"number\"/>.</returns>\n    public override string ConvertToTuple(int number)\n    {\n        // Exact tuple names win first; only unknown tuples fall back to harmony-suffix rendering.\n        if (profile.NamedTuples is not null && profile.NamedTuples.TryGetValue(number, out var namedTuple))\n        {\n            return namedTuple;\n        }\n\n        if (profile.TupleSuffixes is null)\n        {","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer/Localisation/NumberToWords/HarmonyOrdinalNumberToWordsConverter.cs#L130-L166","documentation":"ConvertToOrdinal's switch over profile.OrdinalSuffixStrategy hit its default arm — the profile declared a HarmonyOrdinalSuffixStrategy value the converter does not handle. This is a profile-data / source-generator defect, not user input. It fires during ToOrdinalWords() for a Turkic locale whose ordinal strategy is out of range.","triggerScenarios":"number.ToOrdinalWords(new CultureInfo(<turkic culture>)) where profile.OrdinalSuffixStrategy is neither LastVowelMap nor FinalCharacterMembership.","commonSituations":"Version mismatch where a new enum member was added without a corresponding switch case; hand-authored locale data with an invalid strategy value.","solutions":["Report the locale + version as a library/locale-data bug.","Use a Humanizer version where profile data and the switch agree.","If authoring a locale, set OrdinalSuffixStrategy to LastVowelMap or FinalCharacterMembership."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// OrdinalSuffixStrategy is internal; callers cannot pre-validate. Catch InvalidOperationException\n// from ConvertToOrdinal and fall back to a known-good locale.","typeGuard":null,"tryCatchPattern":"string ordinal;\ntry\n{\n    ordinal = number.ToOrdinalWords(culture);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"harmony-ordinal suffix strategy\"))\n{\n    ordinal = number.ToOrdinalWords(CultureInfo.InvariantCulture);\n}","preventionTips":["Smoke-test ToOrdinalWords for each Turkic locale after a Humanizer upgrade.","Pin a consistent Humanizer version.","Report ordinal-strategy defects upstream."],"tags":["number-to-words","profile-data","internal-invariant","localization"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}