{"record":{"id":"6b3f2397c73e4fac","repo":"Humanizr/Humanizer","slug":"release-duration-case-completeness-requires-zero-u","errorCode":null,"errorMessage":"Release duration-case completeness requires zero unsupported dispositions; found {unsupportedPaths.Length}: {string.Join(\", \", unsupportedPaths)}.","messagePattern":"Release duration-case completeness requires zero unsupported dispositions; found (.+?): (.+?)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Humanizer.SourceGenerators/Common/DurationCaseModels.cs","lineNumber":183,"sourceCode":"                .ToArray();\n            if (legacyCatalogs.Length > 0)\n            {\n                throw new InvalidOperationException(\n                    $\"Release duration-case locales must use the explicit inventory, reason, sources, and provenance contract: {string.Join(\", \", legacyCatalogs)}.\");\n            }\n\n            var unsupportedPathBuilder = ImmutableArray.CreateBuilder<string>();\n            foreach (var catalog in immutableCatalogs)\n            {\n                unsupportedPathBuilder.AddRange(GetUnsupportedPaths(catalog));\n            }\n\n            var unsupportedPaths = unsupportedPathBuilder\n                .OrderBy(static path => path, StringComparer.Ordinal)\n                .ToArray();\n            if (unsupportedPaths.Length > 0)\n            {\n                throw new InvalidOperationException(\n                    $\"Release duration-case completeness requires zero unsupported dispositions; found {unsupportedPaths.Length}: {string.Join(\", \", unsupportedPaths)}.\");\n            }\n\n            return new DurationCaseCoverageInput(immutableCatalogs, rows.MoveToImmutable());\n        }\n\n        internal static void ValidateReleaseCompleteness(DurationCaseCatalog catalog)\n        {\n            var path = $\"{catalog.LocaleCode}.durationCases\";\n            if (catalog.Sources.IsEmpty)\n            {\n                throw new InvalidOperationException(\n                    $\"'{path}' must use the explicit inventory, reason, sources, and provenance contract in a release locale.\");\n            }\n\n            var unsupportedPaths = GetUnsupportedPaths(catalog);\n            if (unsupportedPaths.Length > 0)\n            {","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer.SourceGenerators/Common/DurationCaseModels.cs#L165-L201","documentation":"Thrown by DurationCaseCoverageInput.Create when GetUnsupportedPaths returns any paths across all release locale catalogs. Release completeness requires that no duration-case disposition is left as 'unsupported' — every classification, case realization, and unit must be fully resolved. The message lists the count and the specific paths.","triggerScenarios":"Create iterates all catalogs, collects unsupported paths (classification == Unsupported, or any realization/unit with Kind == Unsupported), and throws if the count is non-zero. For example, a locale with classification: unsupported in a release build triggers '{locale}.durationCases.classification' as an unsupported path.","commonSituations":"A locale is marked 'unsupported' as a placeholder during development but ships in a release. Or a case realization or individual unit is flagged unsupported because the locale data is incomplete. Release builds enforce zero unsupported dispositions.","solutions":["Change the locale's durationCases classification from 'unsupported' to a concrete value: 'distinct', 'invariant', or 'not-applicable'.","If individual case realizations or units are unsupported, provide complete data for them or reclassify the whole locale.","For locales where duration cases truly don't apply, use 'not-applicable' with a reason — not 'unsupported'."],"exampleFix":"# before\ndurationCases:\n  classification: unsupported\n# after\ndurationCases:\n  classification: not-applicable\n  reason: \"Language has no grammatical case system.\"\n  sources: [...]\n  provenance: { ... }","handlingStrategy":"validation","validationCode":"// Pre-check for unsupported dispositions across all catalogs\nstatic List<string> PreviewUnsupportedPaths(ImmutableArray<DurationCaseCatalog> catalogs)\n{\n    var paths = new List<string>();\n    foreach (var catalog in catalogs)\n    {\n        if (catalog.Classification == DurationCaseClassification.Unsupported)\n            paths.Add($\"{catalog.LocaleCode}.durationCases.classification\");\n    }\n    return paths;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["No release locale may use 'classification: unsupported'.","Replace 'unsupported' with 'not-applicable' (with reason) for languages without case systems.","Audit all locale files for 'unsupported' dispositions before tagging a release."],"tags":["source-generator","locale","duration-cases","release-gate","completeness"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}