icsharpcode/ILSpy · error · ReflectionNameParseException
Expected '}'
Error message
Expected '}'
What it means
ReflectionNameParseException thrown by ReadTypeParameterCountFromIdString when a bound type-argument list opened with '{' is never closed with '}' before the end of the string. The arity counter scans for the matching brace and throws at the position just past the end if it runs off the string.
Source
Thrown at ICSharpCode.Decompiler/Documentation/IdStringProvider.cs:1130
{
depth++;
}
else if (c == '}')
{
if (depth == 0)
{
pos++;
return count;
}
depth--;
}
else if (c == ',' && depth == 0)
{
count++;
}
pos++;
}
throw new ReflectionNameParseException(pos, "Expected '}'");
}
return 0;
}
/// <summary>
/// Attempts to resolve a parsed type name within a single module.
/// The first part's Name is a dotted name like "A.B.C", and we try all possible
/// splits between namespace and top-level type name, from right to left.
/// For each candidate top-level type, we walk the nested types.
/// Also checks type forwarders.
/// </summary>
static EntityHandle ResolveTypeInModule(List<TypeNamePart> parts, MetadataFile module)
{
var metadata = module.Metadata;
string topLevelDottedName = parts[0].Name;
string[] dotParts = topLevelDottedName.Split('.');
View on GitHub (pinned to 60c08fcb74)
Solutions
- Close every '{' with a matching '}' in bound type-argument syntax.
- Prefer the unbound arity form (e.g. "T:Foo`2") when you only need the type definition lookup.
- Validate brace balance before passing the ID string to FindEntity.
Example fix
// before
var e = IdStringProvider.FindEntity("T:Foo{System.Int32", context);
// after
var e = IdStringProvider.FindEntity("T:Foo{System.Int32}", context); Defensive patterns
Strategy: try-catch
Validate before calling
static bool BracesBalanced(string s)
{
int depth = 0;
foreach (char c in s)
{
if (c == '{') depth++;
else if (c == '}') depth--;
if (depth < 0) return false;
}
return depth == 0;
} Try / catch
try { return IdStringProvider.FindEntity(idString, context); }
catch (ReflectionNameParseException ex) { logger.Warn($"Unclosed generic args at {ex.Position}: {ex.Message}"); return null; } Prevention
- Prefer the unbound arity form ('T:Foo`2') over bound '{...}' syntax when only arity matters.
- Validate brace balance before passing bound-argument ID strings to FindEntity.
- Catch ReflectionNameParseException for any externally supplied ID string.
When it happens
Trigger: An ID string using bound generic syntax with an unclosed brace, e.g. "T:Foo{Bar" or "T:Foo{Bar,Baz".
Common situations: Truncating a bound-argument ID string; constructing one programmatically and forgetting the closing brace; copying a cref that was itself cut off.
Related errors
- Missing type tag
- Could not find '.' separating type name from member name
- Expected type name
- The handle must not be nil.
- Unsupported handle kind: {handle.Kind}
AI-assisted analysis of icsharpcode/ILSpy@60c08fcb74 (2026-08-13).
Data as JSON: /api/errors/5cfc99648f8ee93f.
Report an issue: GitHub.