egametang/ET · error

config type mismatch: expect=

Error message

config type mismatch: expect={configType.FullName} actual={category.GetType().FullName}

What it means

Thrown by LoadOneConfig when the object returned by factory.Create() has a runtime Type that does not exactly equal the requested configType. The loader keys configs by their declared category Type, so a mismatch means the factory produced the wrong category — a wiring/codegen defect rather than a data problem.

Solutions

  1. Align the factory's ConfigType with the concrete type returned by Create() (they must be the same Type).
  2. If inheritance is intended, relax the exact-equality check to IsAssignableFrom — but only if the design permits.
  3. Re-run codegen so factory and category stay consistent.

Example fix

// before — ConfigType and Create() return type differ
public Type ConfigType => typeof(BaseCategory);
public object Create() => new DerivedCategory(); // GetType() != BaseCategory

// after — make them match
public Type ConfigType => typeof(DivedCategory);
public object Create() => new DerivedCategory();
Defensive patterns

Strategy: validation

Validate before calling

// For factory authors: keep ConfigType and Create() return type identical
Debug.Assert(typeof(MyCategory) == factory.ConfigType);

Type guard

static bool FactoryTypeConsistent(IConfigFactory f)
{
    object o = f.Create();
    return o != null && o.GetType() == f.ConfigType;
}

Prevention

When it happens

Trigger: GetConfigFactory resolved a factory whose ConfigType is X, but Create() returns an instance whose GetType() is Y != X. Happens when a factory's ConfigType and its Create() return type disagree (e.g. factory returns a base class or a sibling category).

Common situations: A factory's ConfigType was edited but Create() wasn't updated; a codegen template mismatch; a factory that returns a derived type where the exact-type check requires the declared category.

Related errors


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/f6bd3525ba448851. Report an issue: GitHub.

Appendix: source

Thrown at Packages/cn.etetet.loader/Scripts/Loader/Share/ConfigLoaderHelper.cs:140

        public static ASingleton LoadOneConfig(Type configType, ConfigFactoryGroupCollection configFactories, Dictionary<Type, IConfig> loadedConfigs)
        {
            ConfigProcessAttribute configProcessAttribute = configType.GetCustomAttributes(typeof(ConfigProcessAttribute), false)[0] as ConfigProcessAttribute;
            if (configProcessAttribute.ConfigType != ConfigType.Code)
            {
                throw new Exception($"unsupported config type: {configProcessAttribute.ConfigType} {configType.FullName}");
            }

            IConfigFactory factory = GetConfigFactory(configType, configFactories);
            object category = factory.Create();
            if (category == null)
            {
                throw new Exception($"config create failed: {configType.FullName}");
            }

            if (category.GetType() != configType)
            {
                throw new Exception($"config type mismatch: expect={configType.FullName} actual={category.GetType().FullName}");
            }

            if (category is not ASingleton singleton)
            {
                throw new Exception($"config singleton invalid: {configType.FullName}");
            }

            if (category is not IConfig iConfig)
            {
                throw new Exception($"config interface invalid: {configType.FullName}");
            }

            loadedConfigs.Add(configType, iConfig);
            return singleton;
        }

        private static string GetConfigGroup(MemberInfo factoryType)
        {

View on GitHub (pinned to 5cab01f7a8)