Editor crashes
Calls that took the Unreal editor down, what each looked like from outside, and how to avoid or recover from it. Read it if an editor died during a session, or before you let an agent drive one.
Every case below has the same first symptom: the call ends with a connection reset or a refused connection, because the process holding the bridge is gone. The cause is almost always an engine check that terminates the process instead of returning an error. Where the current build now refuses the call instead, the note says so. For hangs, where the editor stays up but stops answering, see Editor hangs. For work lost to a crash, see Losing work.
First moves after any crash
- Do not retry the same call. A call that killed an editor once will kill it again.
- Look at the call that was running when it died. A reset connection tells you the editor is gone, not which call did it.
- Before relaunching, move aside the auto-save recovery data if the editor offers to restore it and that prompt has hung before. See Troubleshooting.
- Compile warnings on a Blueprint do not mean it is saved. A clean compile is not durability: save after each stage of a long edit, not at the end.
Cooked assets that cannot be duplicated, analyzed or given collision
What you see. duplicate_asset on a cooked static mesh, add_simplified_collision on a cooked static mesh, or analyze_skeletal_split on a cooked skeletal mesh ends the editor with an access violation. No MifBridge frame appears near the top of the crash stack.
What is happening. Cooking strips the editor-only geometry of a mesh, because the runtime reads baked buffers instead. Engine code that assumes the geometry exists then dereferences nothing. Three separate cases:
- Duplicating a cooked static mesh makes the engine rebuild it from the stripped geometry, which fails a hard check.
- Generating simple collision reads the mesh description directly, and it is null on a cooked mesh.
- Asking a cooked skeletal mesh for its imported model makes the engine wait for data that was stripped and will never arrive. This one was a pure read.
What to do. Do not call these on cooked content. Ask whether the asset is cooked first (describe_package says), and use the read endpoints that answer from the cooked data. A cooked Niagara system or emitter fails the same way on duplicate_asset.
Does the current build protect you. Yes. These calls refuse on cooked content and name the reason, and the editor keeps answering. The general rule still holds for anything you script yourself: on a cooked asset, "does this editor-only getter return null?" is the wrong question, because the getter may not survive being asked. See Cooked projects.
Creating an AnimSequence from nothing
What you see. create_asset with the class AnimSequence succeeds, and the next call that touches the new animation ends the editor.
What is happening. An animation asset needs a skeleton at birth. Created without one, it exists in a state where the first access to its data model fails a hard check. The warning the call used to return ("verify this asset") could not help, because verifying it was the thing that killed the editor.
What to do. Create animations through an endpoint that takes a skeleton, or duplicate an existing clip.
Does the current build protect you. Yes. create_asset refuses every animation base class before it constructs anything, names the reason, and points at the route that works.
Duplicating an animation clip the instant it loads (UE 5.3 to 5.5)
What you see. duplicate_asset of an animation clip that was not yet loaded asserts on a byte-count check, sometimes on the second call, sometimes on the fourth.
What is happening. Loading an animation starts compressing its data on a worker thread. Duplicating serializes that data on the game thread without waiting. If the worker is still writing, the counts disagree and the engine asserts. UE 5.6 added a lock for this; 5.3, 5.4 and 5.5 did not have one.
What to do. On 5.3 to 5.5, if you script your own duplicate of a freshly loaded clip, load it and give it a moment first.
Does the current build protect you. Yes. duplicate_asset waits for the clip's compression to finish before it duplicates.
Removing a widget animation, then adding one with the same name
What you see. remove_widget_animation answers ok: true with remaining: 0. The next add_widget_animation with the same name kills the editor with "Renaming an object ... on top of an existing object ... is not allowed".
What is happening. Removing the animation from the widget's list detached it, but the animation object stayed alive under the widget and kept owning its name. Adding a new one then tried to rename onto a live object, and the engine refuses that with a fatal error. The removal's own check looked at the list, which was empty, so it saw nothing wrong.
What to do. If you must change an animation's length, edit it in place with set_widget_animation_range rather than removing and recreating it.
Does the current build protect you. Yes. Removal moves the object out of the widget's namespace and reports objectNameReusable separately from the removal. add_widget_animation refuses a name that is still held, which also covers an animation hand-deleted in the designer.
splice_into_exec after a macro instance
What you see. Splicing a node in after a macro instance's exec pin (a ForEachLoop's Completed, for example) kills the editor on an assertion about a pin's owning node. Splices after ordinary nodes work fine in the same session.
What is happening. A macro's exec pins are boundary pins of a tunnel, and the splice code walks links it does not expect there.
What to do. Wire it by hand: disconnect_pin the macro's exec output, then two connect_pins calls (macro to the new node, new node to the old target). Inserting a macro into a chain is fine.
Does the current build protect you. Yes. The call refuses to splice after a macro instance and says why.
add_k2_node and nodes that read their own pins as they are placed
What you see. A batched add_k2_node for K2Node_SpawnActorFromClass asserts with "Assertion failed: Result" while looking up a pin, and the editor dies.
What is happening. The engine has two orders for placing a node: allocate its pins then run its post-placement step, or the reverse. Blueprint nodes are written for the first, which is what the action menu does. The bridge used the second, so a node whose post-placement step reads a pin found none. A few other node types (an assign-delegate node among them) read pins the same way.
What to do. Nothing, on the current build.
Does the current build protect you. Yes. Pins are allocated before the post-placement step for Blueprint nodes, as the action menu does.
fix_up_redirectors when a map references the redirector
What you see. fix_up_redirectors with confirm: true after a rename kills a UE 5.7 editor with an assertion about an unset optional value inside the engine's asset tools.
What is happening. When a map references the redirector, the engine's fix-up path loads and unloads that map and asserts. The engine ships no symbols for it, so the exact line is unknown. A redirector referenced only by a material instance does not trigger it.
What to do. Open the map and save it. A level saved after the rename points at the final target, the redirector is no longer referenced, and the next fix-up can delete it.
Does the current build protect you. Yes. A dry run lists referencers and mapReferencers. A real run stops before the engine is called when a map is among them and says how to proceed. allowMapReferencers: true runs the engine path anyway; leave it off unless you have verified your engine survives it.
reload_packages on a package whose file is gone
What you see. After a package's .uasset has been moved or deleted on disk, reload_packages crashes UE 5.8, or fails quietly and crashes the next read of that package on 5.5 and 5.7. UE 5.3, 5.4 and 5.6 passed.
What is happening. The engine's reload of a package with no file behind it is not a clean failure on those versions.
What to do. Do not reload a package whose file you moved away. Check that the file exists first.
Does the current build protect you. Yes. A package with no file comes back in notReloaded with missingFile, and its edits, dirty flag and undo history are kept.
A "Missing Project Settings" toast and a deleted Nanite mesh (UE 5.3 to 5.7)
What you see. Minutes after a Nanite-enabled mesh was deleted, pressing Dismiss on a "Missing Project Settings!" notification kills the editor. Nothing from the bridge is running at that moment.
What is happening. On a project whose graphics settings lack Shader Model 6, the engine raises that toast once per session from the first Nanite mesh, never expires it, and ties its Dismiss button to a raw pointer to the mesh. Deleting the mesh frees it, and Dismiss then reads freed memory. UE 5.8 holds a strong reference and is not affected.
What to do. Dismiss the toast, or enable Shader Model 6 in the project, before deleting a Nanite mesh in a session that showed it.
Does the current build protect you. Yes on 5.3 to 5.7. Every bridge path that deletes or unloads assets, and every undo or redo step, closes the toast first and says so (naniteToastClosed).
Overriding TwoSided on a material instance, then compiling statistics
What you see. set_property sets the TwoSided override on a material instance and reads back true. A later material_statistics with compile: true kills the editor with "Material shader map ... is missing expected shader type FHitProxyVS".
What is happening. In the engine, an instance that already has its own static permutation keeps its old shader map id after the override is written through the property route, so the compiled map says one-sided while the material now says two-sided. The material instance editor avoids this because it writes through a different route. A fresh instance does not show the problem, which is why it is hard to reproduce.
What to do. Nothing, on the current build.
Does the current build protect you. Yes. set_property notes whether the instance's static permutation was updated by the write, forces the engine's own update when it was not, and says so in staticPermutation. material_statistics no longer reads statistics from a shader map that is still incomplete after its compile. Undoing such a write is not covered: avoid undoing a TwoSided override on an instance you plan to compile.
A widget created during Play-In-Editor, then stop_pie
What you see. A test pushes widgets through call_function while PIE runs, then stop_pie kills the editor with "Object 'GameInstance' from PIE level still referenced".
What is happening. Every mutating call is one undo step. A widget created inside it is recorded in the undo history, and the record holds the play session's game instance. When PIE ends, the editor asserts that nothing still references the play world. The same happens when run_python or a console command sets a property on a play-world object.
What to do. Avoid creating or modifying play-world objects from a mutating call you cannot inspect. If you do, expect the undo history to be cleared.
Does the current build protect you. Yes, at two points. Calls that name a live play-world object, and console and Python calls during play, run without the undo step. stop_pie also checks the history for play-world objects and clears it first, answering pieUndoGuard. The price is a cleared undo history, which is what the engine does for play-session objects anyway. self_audit reports the rule.
Optional plugins that are not enabled
What you see. export_trace_trajectory reading curves on a UE 5.6 editor started without the TrajectoryTools plugin ended the editor with a "module not found" exception from a delay-load helper.
What is happening. Declaring a variable of a type from a delay-loaded plugin is already a call into that plugin, including its constructor. With the plugin off, there is nothing to bind to.
What to do. Enable the plugin the endpoint needs, or use an endpoint that does not need it.
Does the current build protect you. Yes. Every path checks the plugin first, loads it if it is enabled but not up, and otherwise refuses naming it with missingPlugin. Reading as curves works without it.
Blueprint breakpoints and modal dialogs
These two do not kill the process, but they look identical from outside, because the editor stops answering.
- A Blueprint breakpoint hit. Play pauses and the engine enters its own debugging loop, which does not run the timer that serves the bridge. Every call times out until someone clicks Resume. From 1.3 the bridge keeps serving a few calls (
blueprint_debuggerreads the stop and resumes, steps or stops play), and a breakpoint hit during a bridge call is continued and reported asbreakpointsPassed. - A dialog that nobody can answer.
set_variable_typeon a variable that already has nodes referencing it opens a "Change Variable Type" confirmation, andduplicate_assetonto a taken name opened a destructive "replace the existing object?" prompt. The bridge stopped answering anything. Both are now guarded: the first proceeds because calling the endpoint is the consent, restoring your own warning preference afterward, and the second refuses a taken destination before the engine is called.
If a call does not return and the editor looks alive, look for a dialog behind the main window first. See Editor hangs.