{"record":{"id":"e4e230f82e0a5db7","repo":"pardeike/Harmony","slug":"must-be-specified-as-namespace-type1-type2-membername","errorCode":null,"errorMessage":" must be specified as 'Namespace.Type1.Type2:MemberName","messagePattern":" must be specified as 'Namespace\\.Type1\\.Type2:MemberName","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Harmony/Tools/Tools.cs","lineNumber":25,"sourceCode":"namespace HarmonyLib\r\n{\r\n\tinternal class Tools\r\n\t{\r\n\t\tinternal static readonly bool isWindows = Environment.OSVersion.Platform.Equals(PlatformID.Win32NT);\r\n\r\n\t\tinternal struct TypeAndName\r\n\t\t{\r\n\t\t\tinternal Type type;\r\n\t\t\tinternal string name;\r\n\t\t}\r\n\r\n\t\tinternal static TypeAndName TypColonName(string typeColonName)\r\n\t\t{\r\n\t\t\tif (typeColonName is null)\r\n\t\t\t\tthrow new ArgumentNullException(nameof(typeColonName));\r\n\t\t\tvar parts = typeColonName.Split(':');\r\n\t\t\tif (parts.Length != 2)\r\n\t\t\t\tthrow new ArgumentException($\" must be specified as 'Namespace.Type1.Type2:MemberName\", nameof(typeColonName));\r\n\t\t\treturn new TypeAndName() { type = TypeByName(parts[0]), name = parts[1] };\r\n\t\t}\r\n\r\n\t\tinternal static void ValidateFieldType<F>(FieldInfo fieldInfo)\r\n\t\t{\r\n\t\t\tvar returnType = typeof(F);\r\n\t\t\tvar fieldType = fieldInfo.FieldType;\r\n\t\t\tif (returnType == fieldType)\r\n\t\t\t\treturn;\r\n\t\t\tif (fieldType.IsEnum)\r\n\t\t\t{\r\n\t\t\t\tvar underlyingType = Enum.GetUnderlyingType(fieldType);\r\n\t\t\t\tif (returnType != underlyingType)\r\n\t\t\t\t\tthrow new ArgumentException(\"FieldRefAccess return type must be the same as FieldType or \" +\r\n\t\t\t\t\t\t$\"FieldType's underlying integral type ({underlyingType}) for enum types\");\r\n\t\t\t}\r\n\t\t\telse if (fieldType.IsValueType)\r\n\t\t\t{\r","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Tools/Tools.cs#L7-L43","documentation":"Tools.TypColonName parses strings of the form 'Namespace.Type:MemberName' into a type plus member name. It throws ArgumentNullException for a null string, and ArgumentException when the string does not contain exactly one ':' (i.e. not exactly two parts after splitting). The thrown message is prefixed with the parameter name by the runtime.","triggerScenarios":"Passing a string with zero or multiple ':' characters to an API that routes through TypColonName, e.g. \"Namespace.Type.Member\" (no colon) or \"A:B:C\" (two colons), or a null string.","commonSituations":"Hand-written patch attribute/target strings where the developer forgot the colon between type and member, or included an assembly-qualified suffix containing extra colons; config-driven patch targets with malformed entries.","solutions":["Format the string exactly as 'FullTypeName:MemberName', e.g. \"My.Namespace.MyType:MyMethod\"","Remove any extra ':' segments (e.g. drop assembly-qualified names or embedded generics/colons) before passing","Ensure the string is non-null; use AccessTools.TypeByName separately when you only need the type"],"exampleFix":"// before\nvar tn = Tools.TypColonName(\"MyNamespace.MyType.MyMethod\"); // missing ':'\n// after\nvar tn = Tools.TypColonName(\"MyNamespace.MyType:MyMethod\");","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(typeColonName) || typeColonName.Split(':').Length != 2)\n    throw new ArgumentException(\"Expected 'Namespace.Type:MemberName'\");","typeGuard":null,"tryCatchPattern":"TypeAndName tn;\ntry { tn = Tools.TypColonName(s); }\ncatch (ArgumentException ex) { throw new FormatException($\"Bad target '{s}', expected 'Namespace.Type:MemberName'\", ex); }","preventionTips":["Keep target strings in the exact 'FullTypeName:MemberName' shape","Validate configured patch targets with a regex like ^[\\w.]+:[\\w`]+$ before use","Never embed assembly-qualified names or extra colons in these strings"],"tags":["argument-exception","string-parsing","reflection"],"backgroundTag":"invalid-argument-format","analyzedSha":"e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c","analyzedAt":"2026-09-15T22:47:11.550Z","contentChangedAt":"2026-09-15T22:47:11.550Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}