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
- Open the named factory type and ensure its ConfigType returns a non-null Type (the config category it produces).
- If the factory is abstract/base, mark it abstract so CreateConfigFactories's 'IsAbstract' filter (line 95) skips it.
- 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
- Always wire ConfigType in factory classes; treat null as a compile-time error.
- Mark base/abstract factories abstract so reflection skips them.
- Add a unit test that instantiates every IConfigFactory and asserts ConfigType != null.
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
- create config factory failed: {factoryType.FullName}
- config type mismatch: expect={configType.FullName} actual={c
- config factory not found: {configType.FullName}
- config group is empty: {factory.GetType().FullName}
- duplicate config factory: {factory.ConfigType.FullName} grou
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/008b866fa0978480.
Report an issue: GitHub.