Humanizr/Humanizer · error · InvalidOperationException
Inflection {subject} contains text outside its declared scri
Error message
Inflection {subject} contains text outside its declared scripts. What it means
After NFC normalization and optional casing, authored text is checked against the inflection owner's declared Unicode scripts. Every letter and mark must belong to one of the scripts declared in the owner's 'scripts:' list. Characters outside the declared scripts (or non-letter characters when allowNonLetters is false) cause rejection.
Source
Thrown at src/Humanizer.SourceGenerators/Generators/ProfileCatalogs/InflectionCatalogValidation.cs:253
if (casing == "lower-title-upper")
{
if (!TryNormalizeSimpleLower(normalized, out var lower))
{
throw new InvalidOperationException(
$"Inflection {subject} has an unsupported casing expansion.");
}
normalized = lower;
}
var literal = allowStemPlaceholder
? normalized.Replace("{stem}", string.Empty)
: normalized;
if (literal.Length > 0 &&
!HasOnlyDeclaredScripts(literal, ownerScripts, allowNonLetters))
{
throw new InvalidOperationException(
$"Inflection {subject} contains text outside its declared scripts.");
}
return normalized;
}
static bool TryNormalizeSimpleLower(string value, out string normalized)
{
var builder = new StringBuilder(value.Length);
for (var index = 0; index < value.Length;)
{
var scalarOffset = index;
var first = value[index++];
int scalar;
if (char.IsHighSurrogate(first))
{
if (index >= value.Length || !char.IsLowSurrogate(value[index]))
{View on GitHub (pinned to ffc2b77c0f)
Solutions
- Add the missing Unicode script name to the owner's 'scripts:' list (e.g., add 'latin' alongside 'cyrillic').
- Remove characters from the authored text that belong to undeclared scripts or are non-letters when not allowed.
- If the field supports non-letters, verify allowStemPlaceholder/allowNonLetters is configured correctly for that call path.
Example fix
# before
owners:
- scripts: ['cyrillic']
lexemes:
- singular:
accepted: ['PDF документ']
# after
owners:
- scripts: ['cyrillic', 'latin']
lexemes:
- singular:
accepted: ['PDF документ'] Defensive patterns
Strategy: validation
Validate before calling
# Before building, verify all letter characters belong to declared scripts.
python3 -c "
import yaml, sys, unicodedata
for f in sys.argv[1:]:
d = yaml.safe_load(open(f))
owners = (d.get('inflection',{}).get('owners') or [])
for owner in owners:
declared = set(owner.get('scripts') or [])
for lex in (owner.get('lexemes') or []):
for v in ((lex.get('singular') or {}).get('accepted') or []):
for ch in v:
if ch.isalpha():
script = unicodedata.name(ch,'').split()[0].lower()
if script not in declared:
print(f'{f}: char {ch!r} script {script!r} not in declared {declared}')
" src/Humanizer/Locales/*.yml Prevention
- Declare every script that appears in the locale's lexeme/rule text in the owner's scripts list.
- When adding loanwords from another script, update the scripts array immediately.
- Avoid non-letter characters (digits, symbols) in fields that set allowNonLetters=false.
When it happens
Trigger: A lexeme or guard text contains characters from a Unicode script not listed in the owner's 'scripts:' array, or contains non-letter characters (digits, punctuation) when allowNonLetters is false. The HasOnlyDeclaredScripts method returns false for the literal.
Common situations: Mixing Latin loanwords into a Cyrillic-script locale without declaring 'latin' in scripts. Using digits or hyphens in form text when the field does not allow non-letters. Adding a new script to forms but forgetting to update the owner's scripts list.
Related errors
- Inflection {subject} contains a duplicate after normalizatio
- Inflection {subject} contains invalid Unicode.
- Inflection {subject} has an unsupported casing expansion.
- Productive evidence '{direction}' requires at least 100 atte
- {subject} references unknown source '{source}'.
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/809346c4c4ab8ecb.
Report an issue: GitHub.