stride3d/stride · error · InvalidOperationException
The replacement asset can't be null when fixing a reference
Error message
The replacement asset can't be null when fixing a reference
What it means
ReferenceReplacementViewModel.FixReference throws InvalidOperationException (not an argument exception) when a replacement is requested but the ReplacementObject property is still null. The method decides between ClearReference and ReplaceReference based on whether a deletion or replacement is being fixed.
Solutions
- Assign ReplacementObject to a valid asset before calling FixReference()
- Force the clear-reference mode instead (ClearReference()) when no replacement is intended
- Disable the fix action in the UI until a replacement is selected
Example fix
// before
viewModel.FixReference();
// after
if (viewModel.ReplacementObject == null)
viewModel.ClearReference();
else
viewModel.FixReference(); Defensive patterns
Strategy: validation
Validate before calling
if (vm.ReplacementObject == null) { vm.ClearReference(); } else { vm.FixReference(); } Type guard
static bool HasReplacement([NotNullWhen(true)] object? r) => r is not null;
Try / catch
try { vm.FixReference(); } catch (InvalidOperationException ex) { logger.LogWarning(ex, "No replacement selected; clearing reference instead"); vm.ClearReference(); } Prevention
- Enable the fix action only after a replacement is chosen
- Decide clear-vs-replace explicitly in calling code
- Validate ReplacementObject before invoking FixReference programmatically
When it happens
Trigger: Calling FixReference() on a reference whose replacement mode is active while the user never picked a replacement asset (ReplacementObject == null).
Common situations: Clicking 'Fix' in the Fix References dialog without selecting a substitute asset, or programmatic fixing where the replacement was not assigned first.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Invoking ShouldStayOpen before the work is finished.
- Container's value is null
- Could not find asset
- Expect name1=value1;name2=value2 format.
- assetItem must be an absolute path
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/effdee49efa594d6.
Report an issue: GitHub.
Appendix: source
Thrown at sources/editor/Stride.Core.Assets.Editor/Components/FixReferences/ReferenceReplacementViewModel.cs:47
public T Referencer { get; }
public T ReplacementObject { get { return replacementObject; } set { SetValue(ref replacementObject, value, () => fixReferences.UpdateCommands()); } }
public bool DontFixReference { get { return dontFixReference; } set { SetValue(ref dontFixReference, value, () => fixReferences.UpdateCommands()); } }
public ICommandBase PickupReplacementObjectCommand { get; }
public void FixReference()
{
if (DontFixReference)
{
ClearReference();
}
else
{
if (ReplacementObject == null)
throw new InvalidOperationException("The replacement asset can't be null when fixing a reference");
ReplaceReference();
}
}
public abstract void ClearReference();
protected abstract void ReplaceReference();
protected async Task PickupReplacementObject()
{
var replacement = await fixReferences.PickupObject(ObjectToFix, propertyType);
if (replacement != null)
{
ReplacementObject = replacement;
}
}
}View on GitHub (pinned to 96fad776d2)