stride3d/stride · error · InvalidOperationException
Unable to reach the game-side instance
Error message
Unable to reach the game-side instance
What it means
GameEditorChangePropagator.Initialize resolves the game-side counterpart of an asset part by asking the controller (on the game thread) to FindGameSidePart for the part's AbsoluteId. If the lookup returns null — the game-side entity/object does not exist — the propagator cannot link asset and game nodes and throws InvalidOperationException.
Solutions
- Ensure the asset is saved/instanced before starting the game preview so game-side parts exist for every asset part.
- Wrap propagator creation in try/catch and re-create the propagator when the game scene reloads.
- Verify the part's AbsoluteId (AssetId + part Id) matches an actual instance in the scene; fix custom tooling that fabricates ids.
Example fix
// before
var gameSide = await controller.InvokeAsync(() => controller.FindGameSidePart(partId));
// after
var gameSide = await controller.InvokeAsync(() => controller.FindGameSidePart(partId));
if (gameSide == null)
logger.Warning($"Part {partId} not instanced game-side; skipping propagation"); Defensive patterns
Strategy: try-catch
Validate before calling
var exists = await controller.InvokeAsync(() => controller.FindGameSidePart(partId) != null); if (!exists) return; // part not instanced game-side
Try / catch
try { await propagator.Initialize(part); }
catch (InvalidOperationException ex) when (ex.Message.Contains("game-side instance")) { logger.Warning($"Skipping uninstanced part {partId}"); } Prevention
- Start the game preview only from saved/instanced scenes
- Re-create propagators when the game scene reloads
- Avoid fabricating part ids in custom tooling
When it happens
Trigger: The asset-side instance (e.g. an entity inside a prefab/composable scene) has no corresponding game-side instance at propagation start: the part was added or renamed between the game start snapshot and propagator initialization, or the part id does not exist in the running scene.
Common situations: Editing a prefab while its instance is live in the game preview; parts created programmatically without being instantiated game-side; race where the game scene loaded a stale version of the scene.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Unable to retrieve the game-side node
- CommandList updating the staging resource has not been…
- The given does not correspond to any existing part.
- The given does not correspond to any existing part.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/4589061d2372366f.
Report an issue: GitHub.
Appendix: source
Thrown at sources/editor/Stride.Assets.Presentation/AssetEditors/GameEditor/ViewModels/GameEditorChangePropagator.cs:77
listener.ValueChanged -= AssetSideNodeChanged;
listener.ItemChanged -= AssetSideNodeChanged;
running = false;
// This will resume the propagator task if it's awaiting, and allow it to complete.
propagatorQueue.Post(null);
}
public void NotifyGameSidePartAdded()
{
gameSideReady.SetResult(0);
}
private async Task Initialize([NotNull] TAssetPart assetSideInstance)
{
var partId = new AbsoluteId(Owner.Id.AssetId, assetSideInstance.Id);
var gameSideInstance = await Editor.Controller.InvokeAsync(() => Editor.Controller.FindGameSidePart(partId));
if (gameSideInstance == null)
throw new InvalidOperationException("Unable to reach the game-side instance");
using (await DispatcherLock.Lock(true, Editor.Controller, Editor.Dispatcher))
{
Editor.Controller.Logger.Debug($"Initial linking for part {assetSideInstance.Id}");
var assetNode = (IAssetNode)Editor.NodeContainer.GetNode(assetSideInstance);
var gameNode = Editor.Controller.GameSideNodeContainer.GetOrCreateNode(gameSideInstance);
gameObjectLinker.LinkGraph(assetNode, gameNode);
}
}
private static void LinkNode(IGraphNode assetNode, IGraphNode gameNode)
{
var node = (IAssetNode)assetNode;
node.SetContent(GameSideContentKey, gameNode);
}
private void AssetSideNodeChanged(object sender, INodeChangeEventArgs e)
{View on GitHub (pinned to 96fad776d2)