egametang/ET · error

config factory target is null: {factory.GetType().FullName}

Error message

config factory target is null: {factory.GetType().FullName}

What it means

Thrown by ConfigFactoryGroupCollection.Add when an IConfigFactory instance has a null ConfigType. ConfigType identifies which config category a factory builds; null means the factory was declared but never assigned a target Type, so it cannot be registered or looked up. This is a wiring/authoring defect in the factory class, surfaced at startup during CreateConfigFactories.

Source

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

using System;
using System.Collections.Generic;
using System.Reflection;

namespace ET
{
    public sealed class ConfigFactoryGroupCollection
    {
        private readonly Dictionary<Type, Dictionary<string, IConfigFactory>> factories = new();

        public void Add(string configGroup, IConfigFactory factory)
        {
            if (factory.ConfigType == null)
            {
                throw new Exception($"config factory target is null: {factory.GetType().FullName}");
            }

            if (string.IsNullOrWhiteSpace(configGroup))
            {
                throw new Exception($"config group is empty: {factory.GetType().FullName}");
            }

            if (!this.factories.TryGetValue(factory.ConfigType, out Dictionary<string, IConfigFactory> groupFactories))
            {
                groupFactories = new Dictionary<string, IConfigFactory>(StringComparer.Ordinal);
                this.factories.Add(factory.ConfigType, groupFactories);
            }

            if (!groupFactories.TryAdd(configGroup, factory))
            {
                throw new Exception($"duplicate config factory: {factory.ConfigType.FullName} group={configGroup}");
            }
        }

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Open the named factory type and ensure its ConfigType returns a non-null Type (the config category it produces).
  2. If the factory is abstract/base, mark it abstract so CreateConfigFactories's 'IsAbstract' filter (line 95) skips it.
  3. Re-run the config codegen so the factory's ConfigType is populated.

Example fix

// before
public class MyItemConfigFactory : IConfigFactory
{
    public Type ConfigType => null; // forgot to wire
}

// after
public class MyItemConfigFactory : IConfigFactory
{
    public Type ConfigType => typeof(ItemConfigCategory);
}
Defensive patterns

Strategy: validation

Validate before calling

// For factory authors — assert at construction
public Type ConfigType => _configType ?? throw new InvalidOperationException(nameof(ConfigType));

Type guard

static bool IsFactoryValid(IConfigFactory f) => f.ConfigType != null;

Prevention

When it happens

Trigger: A class implements IConfigFactory but its ConfigType property/field is left null (e.g. a partial config factory whose target was not set, or a factory generated by a codegen step that omitted the type). Hit during CreateConfigFactories which instantiates every IConfigFactory via reflection and calls Add.

Common situations: A new config factory was added but its ConfigType wasn't wired; a Luban/codegen run produced a factory stub without the target; a base-class factory whose ConfigType is meant to be set by a subclass but is instantiated directly.

Related errors


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