{"record":{"id":"55d7fec2add30913","repo":"egametang/ET","slug":"unsupported-config-type-configprocessattribute-c","errorCode":null,"errorMessage":"unsupported config type: {configProcessAttribute.ConfigType} {configType.FullName}","messagePattern":"unsupported config type: (.+?) (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.loader/Scripts/Loader/Share/ConfigLoaderHelper.cs","lineNumber":128,"sourceCode":"            foreach (Type factoryType in factoryTypes)\n            {\n                if (Activator.CreateInstance(factoryType) is not IConfigFactory factory)\n                {\n                    throw new Exception($\"create config factory failed: {factoryType.FullName}\");\n                }\n\n                factories.Add(GetConfigGroup(factoryType), factory);\n            }\n\n            return factories;\n        }\n\n        public static ASingleton LoadOneConfig(Type configType, ConfigFactoryGroupCollection configFactories, Dictionary<Type, IConfig> loadedConfigs)\n        {\n            ConfigProcessAttribute configProcessAttribute = configType.GetCustomAttributes(typeof(ConfigProcessAttribute), false)[0] as ConfigProcessAttribute;\n            if (configProcessAttribute.ConfigType != ConfigType.Code)\n            {\n                throw new Exception($\"unsupported config type: {configProcessAttribute.ConfigType} {configType.FullName}\");\n            }\n\n            IConfigFactory factory = GetConfigFactory(configType, configFactories);\n            object category = factory.Create();\n            if (category == null)\n            {\n                throw new Exception($\"config create failed: {configType.FullName}\");\n            }\n\n            if (category.GetType() != configType)\n            {\n                throw new Exception($\"config type mismatch: expect={configType.FullName} actual={category.GetType().FullName}\");\n            }\n\n            if (category is not ASingleton singleton)\n            {\n                throw new Exception($\"config singleton invalid: {configType.FullName}\");\n            }","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.loader/Scripts/Loader/Share/ConfigLoaderHelper.cs#L110-L146","documentation":"Thrown by LoadOneConfig when a config type's ConfigProcessAttribute.ConfigType is not ConfigType.Code. LoadOneConfig only handles code-mode configs (it expects to build the category from C# code via a factory); other config kinds (e.g. binary/proto asset-loaded configs) are loaded through a different path and must not reach this method.","triggerScenarios":"GetConfigTypes() returns all types marked with ConfigProcessAttribute; LoadOneConfig is invoked for each, but one was authored/marked as a non-Code config type (e.g. ConfigType.Asset or similar) and was incorrectly routed into the code-loading path.","commonSituations":"A config category's attribute was changed from Code to another type but the loader dispatch still calls LoadOneConfig for it; a new config kind was added without updating the loader's routing logic; misconfigured ConfigProcessAttribute during codegen.","solutions":["Filter config types by ConfigProcessAttribute.ConfigType == ConfigType.Code before calling LoadOneConfig (the caller should route non-Code types elsewhere).","Correct the attribute on the offending config type if it should be Code.","Ensure the loader's dispatch matches the set of ConfigType values produced by codegen."],"exampleFix":"// before — LoadOneConfig called for every config type\nforeach (Type t in configTypes) LoadOneConfig(t, factories, loaded);\n\n// after — route by ConfigType\nforeach (Type t in configTypes)\n{\n    var attr = (ConfigProcessAttribute)t.GetCustomAttributes(typeof(ConfigProcessAttribute), false)[0];\n    if (attr.ConfigType != ConfigType.Code) continue; // handled elsewhere\n    LoadOneConfig(t, factories, loaded);\n}","handlingStrategy":"validation","validationCode":"var attr = (ConfigProcessAttribute)t.GetCustomAttributes(typeof(ConfigProcessAttribute), false)[0];\nif (attr.ConfigType != ConfigType.Code) { /* route to non-code loader */ return; }\nConfigLoaderHelper.LoadOneConfig(t, factories, loaded);","typeGuard":"static bool IsCodeConfig(Type t)\n{\n    var attr = (ConfigProcessAttribute)t.GetCustomAttributes(typeof(ConfigProcessAttribute), false).FirstOrDefault();\n    return attr != null && attr.ConfigType == ConfigType.Code;\n}","tryCatchPattern":null,"preventionTips":["Filter config types by ConfigType before dispatching to LoadOneConfig.","Keep the loader's routing in sync with the set of ConfigType values codegen emits.","Document which ConfigType values each load path handles."],"tags":["loader","config","configtype","attribute","routing"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}