{"record":{"id":"cdacc88d5fa8078a","repo":"Humanizr/Humanizer","slug":"phrase-path-must-be-a-scalar-string","errorCode":null,"errorMessage":"Phrase '{path}' must be a scalar string.","messagePattern":"Phrase '(.+?)' must be a scalar string\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Humanizer.SourceGenerators/Common/LocalePhraseNormalization.cs","lineNumber":478,"sourceCode":"                if (!placeholders.Contains(placeholderName))\n                {\n                    placeholders.Add(placeholderName);\n                }\n            }\n\n            return new NamedTemplatePhrase(templateName, template, placeholders.ToImmutable());\n        }\n\n        static string? GetOptionalLiteral(SimpleYamlMapping mapping, string key, string path, params string[] allowedPlaceholders)\n        {\n            if (!mapping.TryGetValue(key, out var value))\n            {\n                return null;\n            }\n\n            if (value is not SimpleYamlScalar scalar)\n            {\n                throw new InvalidOperationException($\"Phrase '{path}' must be a scalar string.\");\n            }\n\n            if (!scalar.IsQuoted && string.Equals(scalar.Value, \"null\", StringComparison.Ordinal))\n            {\n                return null;\n            }\n\n            return ValidateLiteralText(path, scalar.Value, allowedPlaceholders);\n        }\n\n        static string? GetOptionalLiteralOrExplicitTemplate(SimpleYamlMapping mapping, string key, string path)\n        {\n            if (!mapping.TryGetValue(key, out var value))\n            {\n                return null;\n            }\n\n            if (value is SimpleYamlScalar scalar)","sourceCodeStart":460,"sourceCodeEnd":496,"githubUrl":"https://github.com/Humanizr/Humanizer/blob/ffc2b77c0f30d2fb176875841424379319d0ae9b/src/Humanizer.SourceGenerators/Common/LocalePhraseNormalization.cs#L460-L496","documentation":"Thrown by GetOptionalLiteral when a YAML key that must hold a scalar string (e.g. symbol, default, beforeCount, now) is instead a mapping or sequence. Literal phrase fields only accept scalars (an unquoted 'null' is treated as absent). Surfaced as compiler diagnostic HSG003 (severity Error).","triggerScenarios":"Writing 'default:\n  singular: ...' under a field that expects a plain string, or putting a list where a scalar is required; wrong indentation merging a child mapping under a literal key.","commonSituations":"Indentation slip that nests the next unit's keys under the current literal; author treats a literal field as a forms block; copy-paste of a mapping into a scalar slot.","solutions":["Replace the mapping/sequence with a scalar string value for that key.","Fix YAML indentation so sibling keys are not accidentally nested under the literal field.","Move the nested content to the correct parent (e.g. under 'forms:') if it was meant to be form data.","Rebuild to confirm the diagnostic clears."],"exampleFix":"# before\ndataUnits:\n  byte:\n    symbol:\n      singular: B\n# after\ndataUnits:\n  byte:\n    symbol: B","handlingStrategy":"validation","validationCode":"# Literal fields (symbol, default, zero, singular, dual, paucal, plural, many,\n# beforeCount, afterCount, now, today, never) must be scalars.\nyq -o=json '[.. | select(tag == \"!!map\") | to_entries[] | select(.key | test(\"^(symbol|default|zero|singular|dual|paucal|plural|many|beforeCount|afterCount|now|today|never)$\")) | select(.value | tag != \"!!str\")] ' src/Humanizer/Locales/<code>.yml","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep literal fields as single-line scalars.","Watch indentation so the next unit does not nest under a literal key.","Build after structural edits."],"tags":["humanizer","source-generator","locale","yaml","localization","phrases","scalar","indentation"],"backgroundTag":null,"analyzedSha":"ffc2b77c0f30d2fb176875841424379319d0ae9b","analyzedAt":"2026-08-13T21:42:34.584Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}