save_asset
Write one Unreal .uasset package to disk and verify it persisted using still_dirty_after_save:false and file_on_disk:true, not just a success flag.
Instructions
Write ONE .uasset to disk by package path (a Blueprint, DataTable, material...) and VERIFY the effect: still_dirty_after_save:false plus file_on_disk:true is the oracle, not saved. Use save_level for the .umap and reload_asset_package to undo an in-memory edit instead. PIE: this is REFUSED while Play-in-Editor runs (it never stops or touches your session) -- the engine guard Editor.AllowSavingAssetsDuringPIE=0 rejects the write before attempting anything, so a save during play would report success without writing a byte. Stop PIE and retry, or pass force=true. WARNING: when it answers success:false with PIE down, a common cause is the file being READ-ONLY on disk (e.g. a Git LFS lockable file that has not been git lfs locked). You do not have to check that by hand: file_read_only is measured on every call and the error message states whether a read-only file IS or is NOT the explanation. WARNING: it writes exactly one package, so it cannot stop a compile cascade from dirtying a vendored asset that a LATER bulk save then rewrites -- list_dirty_packages before, git status after.
Returns: { path: string, package_name: string, saved: bool, success: bool, under_readonly_root: bool, readonly_root_matched: string, refused_readonly: bool, readonly_roots: [string], readonly_roots_defaulted: bool, still_dirty_after_save: bool, file_on_disk: bool, file_read_only: bool (measured on disk -- true means the file is read-only, e.g. an unlocked Git LFS lockable file), verification: object, verification_checks: [object], error?: string }
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Full asset path to save, e.g. /Game/MyGame/Core/BP_MyActor (an .Object suffix is tolerated). Must already exist or the call errors. | |
| force | No | Optional. This command is REFUSED while a Play-in-Editor session is running: it either compiles a Blueprint (the reinstancer can retain a world, and CheckForWorldGCLeaks is Fatal -- it KILLS the editor) or writes to disk (Editor.AllowSavingAssetsDuringPIE=0 makes the engine refuse the write, so it would report success without writing a byte). Stop PIE and retry instead; force=true runs it anyway, at your own risk. | |
| asset_path | No | Alias of `path` (same value, same meaning). Accepted because sibling tools spell this parameter differently; prefer `path`. | |
| readonly_roots | No | Optional array of long-path prefixes treated as vendored/upstream (default: the project's Read Only Content Roots). A save under one of them is REFUSED by default; see refuse_readonly. Pass [] to disable the classification entirely. | |
| refuse_readonly | No | Optional bool. When true, a save whose package falls under one of readonly_roots is REFUSED (success:false, saved:false, refused_readonly:true) instead of performed. Default = the process-wide switch (mcp_common::IsReadOnlyRootSaveEnforcementEnabled(), true unless `mcp.ReadOnlyRootEnforcement 0`); when false the write happens and is only reported + ledgered. |