Humanizr/Humanizer · error · InvalidOperationException
Inflection source '{entry.Key}' {optionalProperty} must be a
Error message
Inflection source '{entry.Key}' {optionalProperty} must be a non-empty scalar. What it means
The optional 'revision' and 'credit' fields on a source definition must be non-empty scalar strings when present. This is a secondary check after ValidateSourceDefinitions confirms kind/locator — it ensures that if a source opts into provenance detail fields, those fields carry real data rather than whitespace or empty strings.
Source
Thrown at src/Humanizer.SourceGenerators/Generators/ProfileCatalogs/InflectionCatalogValidation.cs:130
if (entry.Value is not SimpleYamlMapping source ||
source.GetScalar("kind") is not { Length: > 0 } ||
source.GetScalar("locator") is not { Length: > 0 })
{
throw new InvalidOperationException(
$"Inflection source '{entry.Key}' must define non-empty kind and locator.");
}
ValidateProperties(
source,
$"Inflection source '{entry.Key}'",
"kind", "locator", "revision", "credit");
foreach (var optionalProperty in new[] { "revision", "credit" })
{
if (source.TryGetValue(optionalProperty, out var optionalValue) &&
(optionalValue is not SimpleYamlScalar optionalScalar ||
string.IsNullOrWhiteSpace(optionalScalar.Value)))
{
throw new InvalidOperationException(
$"Inflection source '{entry.Key}' {optionalProperty} must be a non-empty scalar.");
}
}
}
}
static void ValidateTemplate(string ruleId, string template)
{
var marker = template.IndexOf("{stem}", StringComparison.Ordinal);
var remainder = template.Replace("{stem}", string.Empty);
if (marker < 0 ||
template.IndexOf("{stem}", marker + "{stem}".Length, StringComparison.Ordinal) >= 0 ||
remainder.Contains('{') ||
remainder.Contains('}'))
{
throw new InvalidOperationException(
$"Inflection rule '{ruleId}' output must contain exactly one bounded '{{stem}}' placeholder.");
}View on GitHub (pinned to ffc2b77c0f)
Solutions
- Fill the 'revision' or 'credit' field with a meaningful non-empty string value.
- Remove the empty 'revision' or 'credit' key entirely if provenance detail is not needed — both are optional.
- Ensure the value is a plain scalar, not a nested map or list.
Example fix
# before
sources:
custom1:
kind: 'dictionary'
locator: '...'
revision: ''
# after
sources:
custom1:
kind: 'dictionary'
locator: '...'
revision: '2024-03-15' Defensive patterns
Strategy: validation
Validate before calling
# Before building, verify revision/credit fields are non-empty scalars when present.
python3 -c "
import yaml, sys
for f in sys.argv[1:]:
d = yaml.safe_load(open(f))
sources = (d.get('inflection',{}).get('sources') or {})
for sid, sdef in sources.items():
if not isinstance(sdef, dict): continue
for opt in ('revision','credit'):
if opt in sdef:
val = sdef[opt]
if not isinstance(val, str) or not val.strip():
print(f'{f}: source {sid!r} {opt} must be non-empty scalar')
" src/Humanizer/Locales/*.yml Prevention
- If revision/credit are not yet known, omit the keys entirely rather than leaving empty strings.
- Treat source definitions as complete records — fill all fields or remove optional ones.
- Add a lint rule that flags empty-string values for optional provenance fields.
When it happens
Trigger: A source entry includes 'revision:' or 'credit:' but the value is not a SimpleYamlScalar or is a scalar containing only whitespace. For example, 'revision: ""' or 'credit:' with a null/empty value.
Common situations: Adding a placeholder 'revision:' key intending to fill it later. Copying a source template and leaving 'credit:' as an empty string. Accidentally indenting a value onto the next line so the scalar is empty.
Related errors
- {subject} references unknown source '{source}'.
- Inflection source '{entry.Key}' must define non-empty kind a
- '{path}' must define provenance.
- '{path}.provenance' must be a sequence.
- '{path}.provenance' must contain non-empty source identifier
AI-assisted analysis of Humanizr/Humanizer@ffc2b77c0f (2026-08-13).
Data as JSON: /api/errors/11f82df4301f0d06.
Report an issue: GitHub.