{"record":{"id":"9727618c9043e6a8","repo":"egametang/ET","slug":"condition-node-owner-key-field-must-be-string-no","errorCode":null,"errorMessage":"condition node owner key field must be string: {node.GetType().FullName}.{nameof(BTNumericCompare.OwnerKey)}","messagePattern":"condition node owner key field must be string: (.+?)\\.(.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionExprParser.cs","lineNumber":291,"sourceCode":"            if (fieldInfo == null)\n            {\n                throw new Exception($\"condition node field not found: {node.GetType().FullName}.{fieldName}\");\n            }\n\n            fieldInfo.SetValue(node, value);\n        }\n\n        private void SetOwnerKeyField(BTCondition node, string ownerKey)\n        {\n            FieldInfo fieldInfo = node.GetType().GetField(nameof(BTNumericCompare.OwnerKey), BindingFlags.Instance | BindingFlags.Public);\n            if (fieldInfo == null)\n            {\n                throw new Exception($\"condition node owner key field not found: {node.GetType().FullName}.{nameof(BTNumericCompare.OwnerKey)}\");\n            }\n\n            if (fieldInfo.FieldType != typeof(string))\n            {\n                throw new Exception($\"condition node owner key field must be string: {node.GetType().FullName}.{nameof(BTNumericCompare.OwnerKey)}\");\n            }\n\n            fieldInfo.SetValue(node, ownerKey);\n        }\n\n        private void SetParamsField(BTCondition node, string[] paramValues)\n        {\n            FieldInfo fieldInfo = node.GetType().GetField(\"Params\", BindingFlags.Instance | BindingFlags.Public);\n            if (fieldInfo == null)\n            {\n                throw new Exception($\"condition node params field not found: {node.GetType().FullName}.Params\");\n            }\n\n            if (fieldInfo.FieldType != typeof(string[]))\n            {\n                throw new Exception($\"condition node params field must be string[]: {node.GetType().FullName}.Params\");\n            }\n","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.conditionexpr/Scripts/Model/Share/ConditionExprParser.cs#L273-L309","documentation":"Thrown by SetOwnerKeyField after the `OwnerKey` field was found by reflection but its declared type is not exactly `string`. The owner-key value passed in is a string (the part before the dot), so any other field type cannot be assigned and is rejected to avoid a silent type mismatch.","triggerScenarios":"Declaring `public int OwnerKey;` or `public Guid OwnerKey;` on a custom condition node and then using the `OwnerKey.Variable` dotted syntax.","commonSituations":"A developer models the owner as an int id and reuses the canonical name `OwnerKey` for it; type was widened to a custom struct during a refactor.","solutions":["Change the field to `public string OwnerKey;` (the canonical contract).","If you need an int id internally, keep `public string OwnerKey;` for the parser and resolve it to an id inside the node's execution."],"exampleFix":"// before\npublic int OwnerKey;\n// after\npublic string OwnerKey;","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static bool OwnerKeyIsString(Type t)\n{\n    var f = t.GetField(\"OwnerKey\", BindingFlags.Instance | BindingFlags.Public);\n    return f != null && f.FieldType == typeof(string);\n}","tryCatchPattern":null,"preventionTips":["Always declare OwnerKey as `public string`.","If an int id is needed, keep OwnerKey as the string key and resolve it inside the node.","Scan registered nodes in a test to assert OwnerKey field type."],"tags":["csharp","unity","conditionexpr","reflection","attribute"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}