OpenRA/OpenRA · error · NotImplementedException

FieldLoader: Missing field `{s}` on `{f.Name}`

Error message

FieldLoader: Missing field `{s}` on `{f.Name}`

What it means

Thrown by FieldLoader.UnknownFieldAction when a YAML key does not correspond to any field or property on the target type, or when no type parser or TypeConverter can handle a value. Despite the NotImplementedException type, this is a deliberate hard-stop: OpenRA does not silently ignore unknown fields by default - it treats unrecognized YAML keys as errors to catch typos and stale config.

Source

Thrown at OpenRA.Game/FieldLoader.cs:55

				{
					return (string.IsNullOrEmpty(Header) ? "" : Header + ": ") + Missing[0]
						+ string.Concat(Missing.Skip(1).Select(m => ", " + m));
				}
			}

			public MissingFieldsException(string[] missing, string header = null, string headerSingle = null)
				: base(null)
			{
				Header = missing.Length > 1 ? header : headerSingle ?? header;
				Missing = missing;
			}
		}

		public static Func<string, Type, string, object> InvalidValueAction = (s, t, f) =>
			throw new YamlException($"FieldLoader: Cannot parse `{s}` into `{f}.{t}`");

		public static Action<string, Type> UnknownFieldAction = (s, f) =>
			throw new NotImplementedException($"FieldLoader: Missing field `{s}` on `{f.Name}`");

		static readonly ConcurrentCache<Type, FieldLoadInfo[]> TypeLoadInfo =
			new(BuildTypeLoadInfo);
		static readonly ConcurrentCache<string, BooleanExpression> BooleanExpressionCache =
			new(expression => new BooleanExpression(expression));
		static readonly ConcurrentCache<string, IntegerExpression> IntegerExpressionCache =
			new(expression => new IntegerExpression(expression));

		static readonly FrozenDictionary<Type, Func<string, Type, string, object>> TypeParsers =
			new Dictionary<Type, Func<string, Type, string, object>>
			{
				{ typeof(int), ParseInt },
				{ typeof(ushort), ParseUShort },
				{ typeof(long), ParseLong },
				{ typeof(float), ParseFloat },
				{ typeof(decimal), ParseDecimal },
				{ typeof(string), ParseString },
				{ typeof(Color), ParseColor },

View on GitHub (pinned to a520984d91)

Solutions

  1. Check the field name in the error message for typos - it must exactly match a field declared on the target type.
  2. Look up the target type's source code to find the correct field name (the type name is in the message as f.Name).
  3. If the field was renamed or removed in a mod update, update the YAML to use the new field name or remove the obsolete entry.
  4. If you intentionally want unknown fields ignored, you can reassign FieldLoader.UnknownFieldAction to a no-op delegate, but this is strongly discouraged in production.

Example fix

# before - misspelled field
Building:
  Adjacent: false  # no such field

# after - correct field name from Building.cs
Building:
  AllowInvalidPlacement: false
Defensive patterns

Strategy: validation

Validate before calling

// Before loading YAML into a type, verify all keys are known fields
var knownFields = new HashSet<string>(
    target.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
        .Select(f => f.Name));
foreach (var key in miniYaml.ToDictionary().Keys)
    if (!knownFields.Contains(key))
        Console.WriteLine($"Warning: unknown field '{key}' on type {target.GetType().Name}");

Try / catch

try
{
    FieldLoader.LoadFieldOrProperty(target, key, value);
}
catch (NotImplementedException e)
{
    Console.WriteLine($"Unknown field: {e.Message}");
}

Prevention

When it happens

Trigger: Triggered from LoadFieldOrProperty when the key matches no public/non-public field or property on the target object. Also triggered from GetValue when no TypeParser, array parser, enum parser, or TypeConverter can handle the field type, passing '[Type] {value}' as the field name. Common in rules YAML with a misspelled field name or a field removed in a newer mod version.

Common situations: Misspelled field names in trait definitions (e.g. Armout instead of Armor). A mod was updated and a field was renamed or removed, but old YAML still references it. A field name from one trait type accidentally used on a different trait. Copy-pasting trait configuration between incompatible trait types.

Related errors


AI-assisted analysis of OpenRA/OpenRA@a520984d91 (2026-08-13). Data as JSON: /api/errors/4a48813b86a93afa. Report an issue: GitHub.