{"record":{"id":"5cfc99648f8ee93f","repo":"icsharpcode/ILSpy","slug":"expected","errorCode":null,"errorMessage":"Expected '}'","messagePattern":"Expected '\\}'","errorType":"exception","errorClass":"ReflectionNameParseException","httpStatus":null,"severity":"error","filePath":"ICSharpCode.Decompiler/Documentation/IdStringProvider.cs","lineNumber":1130,"sourceCode":"\t\t\t\t\t{\r\n\t\t\t\t\t\tdepth++;\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse if (c == '}')\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tif (depth == 0)\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tpos++;\r\n\t\t\t\t\t\t\treturn count;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tdepth--;\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse if (c == ',' && depth == 0)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tcount++;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tpos++;\r\n\t\t\t\t}\r\n\t\t\t\tthrow new ReflectionNameParseException(pos, \"Expected '}'\");\r\n\t\t\t}\r\n\r\n\t\t\treturn 0;\r\n\t\t}\r\n\r\n\t\t/// <summary>\r\n\t\t/// Attempts to resolve a parsed type name within a single module.\r\n\t\t/// The first part's Name is a dotted name like \"A.B.C\", and we try all possible\r\n\t\t/// splits between namespace and top-level type name, from right to left.\r\n\t\t/// For each candidate top-level type, we walk the nested types.\r\n\t\t/// Also checks type forwarders.\r\n\t\t/// </summary>\r\n\t\tstatic EntityHandle ResolveTypeInModule(List<TypeNamePart> parts, MetadataFile module)\r\n\t\t{\r\n\t\t\tvar metadata = module.Metadata;\r\n\t\t\tstring topLevelDottedName = parts[0].Name;\r\n\t\t\tstring[] dotParts = topLevelDottedName.Split('.');\r\n\r","sourceCodeStart":1112,"sourceCodeEnd":1148,"githubUrl":"https://github.com/icsharpcode/ILSpy/blob/60c08fcb74fcc183130f73c861ed35cf944d0bf1/ICSharpCode.Decompiler/Documentation/IdStringProvider.cs#L1112-L1148","documentation":"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.","triggerScenarios":"An ID string using bound generic syntax with an unclosed brace, e.g. \"T:Foo{Bar\" or \"T:Foo{Bar,Baz\".","commonSituations":"Truncating a bound-argument ID string; constructing one programmatically and forgetting the closing brace; copying a cref that was itself cut off.","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."],"exampleFix":"// before\nvar e = IdStringProvider.FindEntity(\"T:Foo{System.Int32\", context);\n\n// after\nvar e = IdStringProvider.FindEntity(\"T:Foo{System.Int32}\", context);","handlingStrategy":"try-catch","validationCode":"static bool BracesBalanced(string s)\n{\n    int depth = 0;\n    foreach (char c in s)\n    {\n        if (c == '{') depth++;\n        else if (c == '}') depth--;\n        if (depth < 0) return false;\n    }\n    return depth == 0;\n}","typeGuard":null,"tryCatchPattern":"try { return IdStringProvider.FindEntity(idString, context); }\ncatch (ReflectionNameParseException ex) { logger.Warn($\"Unclosed generic args at {ex.Position}: {ex.Message}\"); return null; }","preventionTips":["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."],"tags":["id-string","parse","reflection-name","generic-arity"],"backgroundTag":null,"analyzedSha":"60c08fcb74fcc183130f73c861ed35cf944d0bf1","analyzedAt":"2026-08-13T11:34:51.223Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}