Unity-Technologies/UnityCsReference · error · ArgumentNullException
type
Error message
type
What it means
AssetIdentifier pairs a System.Type with a name to identify a source asset inside the SpeedTree importer pipeline. The AssetIdentifier(Type, string) constructor guards its first argument: a null Type is rejected with ArgumentNullException because the identifier stores type.ToString() and a null Type would otherwise surface as a NullReferenceException much later during serialization/remapping. The check keeps the failure local and the message specific.
Source
Thrown at Editor/Mono/AssetPipeline/SpeedTree/SpeedTreeImporterSettings.cs:154
public string type;
public string name;
public AssetIdentifier(UnityEngine.Object asset)
{
if (asset == null)
{
throw new ArgumentNullException("asset");
}
this.type = asset.GetType().ToString();
this.name = asset.name;
}
public AssetIdentifier(Type type, string name)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
if (name == null)
{
throw new ArgumentNullException("name");
}
if (string.IsNullOrEmpty(name))
{
throw new ArgumentException("The name is empty", "name");
}
this.type = type.ToString();
this.name = name;
}
}
/// <summary>View on GitHub (pinned to 225b0fbdb5)
Solutions
- Resolve the Type before constructing and validate it is non-null (e.g. var t = Type.GetType(typeName); if (t == null) throw new InvalidOperationException("Unknown type " + typeName);).
- If the type came from reflection, prefer typeof(KnownType) or a known assembly-qualified name so the lookup cannot silently fail.
- Catch the failure at the boundary (config load) and report the offending type name rather than letting it reach the constructor.
Example fix
// before
var id = new AssetIdentifier(Type.GetType(cfg.typeName), cfg.name);
// after
var t = Type.GetType(cfg.typeName);
if (t == null)
throw new InvalidOperationException("Unknown type: " + cfg.typeName);
var id = new AssetIdentifier(t, cfg.name); Defensive patterns
Strategy: validation
Validate before calling
Type ResolveType(string typeName) {
var t = Type.GetType(typeName);
if (t == null)
throw new InvalidOperationException("Unknown type: " + typeName);
return t;
}
// then: new AssetIdentifier(ResolveType(cfg.typeName), cfg.name); Type guard
static bool IsValidIdentifierType(Type t) => t != null;
Prevention
- Prefer typeof(T) over Type.GetType(string) so unresolved types fail at compile time.
- When loading types by name, always null-check the result and report the name.
- Keep type names in config assembly-qualified to survive renames and moves.
When it happens
Trigger: Calling new AssetIdentifier(null, someName); passing a Type obtained via Type.GetType(typeName) or assembly.GetType(typeName) where the lookup silently returned null; building identifiers from deserialized config whose type field failed to resolve.
Common situations: Type-load-by-name that fails after a rename or after moving a class between assemblies; config/asset references that name a type no longer present after a Unity upgrade; unit tests scaffolding identifiers with a placeholder null.
Related errors
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/a87515cc2b8d4e86.
Report an issue: GitHub.