Skip to content

fix: save prefab stage edits using the correct prefab-stage workflow#1056

Open
jacklaplante wants to merge 1 commit intoCoplayDev:betafrom
jacklaplante:codex/fix-prefab-stage-save
Open

fix: save prefab stage edits using the correct prefab-stage workflow#1056
jacklaplante wants to merge 1 commit intoCoplayDev:betafrom
jacklaplante:codex/fix-prefab-stage-save

Conversation

@jacklaplante
Copy link
Copy Markdown

@jacklaplante jacklaplante commented Apr 11, 2026

Description

Fixes prefab-stage saving so save_prefab_stage writes the prefab asset instead of trying to save the preview scene.

Type of Change

Save your change type

  • Bug fix (non-breaking change that fixes an issue)
  • Test update

Changes Made

  • changed save_prefab_stage to save prefabStage.prefabContentsRoot back to prefabStage.assetPath
  • reused the same save path from close_prefab_stage(saveBeforeClose: true)
  • added focused EditMode regressions for explicit save and save-before-close persistence

Testing/Screenshots/Recordings

  • Ran Unity EditMode tests in batch mode with -testFilter ManagePrefabsStageTests
  • Result: 7 passed, 0 failed

Documentation Updates

  • I have added/removed/modified tools or resources
  • If yes, I have updated all documentation files using:
    • The LLM prompt at tools/UPDATE_DOCS_PROMPT.md (recommended)
    • Manual updates following the guide at tools/UPDATE_DOCS.md

Related Issues

Fixes #1055

Additional Notes

  • Kept the change narrow to prefab-stage save behavior only.
  • Did not change unrelated prefab editing flows or headless prefab modification behavior.

Summary by Sourcery

Fix prefab stage saving to correctly persist changes to the underlying prefab asset and reuse a shared save workflow for explicit saves and save-before-close.

Bug Fixes:

  • Ensure save_prefab_stage writes modifications from the prefab stage back to the prefab asset instead of attempting to save the preview scene.
  • Ensure close_prefab_stage with saveBeforeClose persists prefab content changes reliably.

Enhancements:

  • Introduce a shared TrySavePrefabStage helper to centralize prefab stage save behavior across commands.

Tests:

  • Add EditMode tests to verify save_prefab_stage persists prefab child changes to disk.
  • Add EditMode tests to verify close_prefab_stage with saveBeforeClose correctly saves and closes the prefab stage.

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Refined prefab stage save workflow to enhance reliability when persisting changes made during prefab editing sessions. Changes now save correctly when you save or close the prefab stage.
    • Improved error handling with clearer diagnostic messages when prefab save operations encounter issues, including permission problems and missing content scenarios.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 11, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7a89275c-f8bf-4815-a7b6-c13074719da8

📥 Commits

Reviewing files that changed from the base of the PR and between 6948193 and da0bd24.

📒 Files selected for processing (2)
  • MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs
  • TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManagePrefabsStageTests.cs

📝 Walkthrough

Walkthrough

Replaced prefab-stage scene-save logic with prefab-asset-save workflow by introducing a private helper method TrySavePrefabStage(...) that calls PrefabUtility.SaveAsPrefabAsset() instead of EditorSceneManager.SaveScene(). Added comprehensive tests verifying that prefab content changes persist correctly after save and close operations.

Changes

Cohort / File(s) Summary
Prefab Stage Save Mechanism
MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs
Replaced scene-based save flow with prefab-asset save via new TrySavePrefabStage() helper. Now calls PrefabUtility.SaveAsPrefabAsset(), clears dirtiness, and refreshes asset database. Updated error handling in SavePrefabStage() and ClosePrefabStage() to funnel through the helper and return specific error messages.
Prefab Stage Persistence Tests
TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManagePrefabsStageTests.cs
Added two new NUnit tests exercising prefab stage save/close workflows: SavePrefabStage_PersistsPrefabContentChanges and ClosePrefabStage_SaveBeforeClose_PersistsChanges. Introduced helper AssertOpenPrefabStage() for consistent prefab stage setup in tests.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • #611 — Directly modifies the same prefab-stage save/close flow in ManagePrefabs.cs with similar refactoring of scene-save to asset-save operations.
  • #627 — Manages prefab-stage dirtiness tracking, complementing this PR's changes to when and how stages are marked dirty during save operations.
  • #1013 — Adds or manages prefab-stage save/close functionality that this PR directly modifies and refactors.

Poem

🐰 A prefab now saves, not as a scene,
But as an asset—how pristine!
No preview-stage confusion here,
Just PrefabUtility, crystal clear.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: fixing prefab stage save behavior to use the correct workflow instead of attempting to save preview scenes.
Description check ✅ Passed The description comprehensively covers all required sections: clear problem statement, type of change identified, specific changes listed, test results provided, and related issue linked.
Linked Issues check ✅ Passed The PR fully addresses the requirements in issue #1055: replaces scene-save APIs with PrefabUtility.SaveAsPrefabAsset, saves prefabContentsRoot to assetPath, reuses save logic across explicit save and save-before-close flows, and adds focused regression tests.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the prefab-stage save behavior identified in #1055; no unrelated modifications to other prefab flows or headless operations are present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai bot commented Apr 11, 2026

Reviewer's Guide

Unifies and fixes prefab-stage saving by introducing a shared helper that persists changes from the prefab contents root back to the prefab asset path, and adds focused EditMode tests to verify explicit save and save-before-close behavior.

Sequence diagram for explicit save_prefab_stage command using TrySavePrefabStage

sequenceDiagram
    actor User
    participant ManagePrefabs
    participant PrefabStage
    participant PrefabUtility
    participant AssetDatabase

    User->>ManagePrefabs: SavePrefabStage()
    ManagePrefabs->>PrefabStage: get_current_prefab_stage()
    alt prefabStage is null
        ManagePrefabs-->>User: ErrorResponse(Not in prefab editing mode)
    else prefabStage exists
        ManagePrefabs->>ManagePrefabs: TrySavePrefabStage(prefabStage, prefabPath, errorMessage)
        alt prefab contents root missing or save failed
            ManagePrefabs-->>User: ErrorResponse(errorMessage)
        else save succeeded
            ManagePrefabs->>PrefabUtility: SaveAsPrefabAsset(prefabContentsRoot, prefabPath, saved)
            PrefabUtility-->>ManagePrefabs: saved = true
            ManagePrefabs->>PrefabStage: ClearDirtiness()
            ManagePrefabs->>AssetDatabase: SaveAssets()
            ManagePrefabs->>AssetDatabase: Refresh()
            ManagePrefabs-->>User: SuccessResponse("Saved prefab stage changes", prefabPath, saved = true)
        end
    end
Loading

Sequence diagram for close_prefab_stage with saveBeforeClose using shared TrySavePrefabStage

sequenceDiagram
    actor User
    participant ManagePrefabs
    participant PrefabStage
    participant PrefabUtility
    participant AssetDatabase

    User->>ManagePrefabs: ClosePrefabStage(saveBeforeClose = true)
    ManagePrefabs->>PrefabStage: get_current_prefab_stage()
    alt prefabStage is null
        ManagePrefabs-->>User: ErrorResponse(Not in prefab editing mode)
    else prefabStage exists
        ManagePrefabs->>ManagePrefabs: TrySavePrefabStage(prefabStage, prefabPath, errorMessage)
        alt save failed
            ManagePrefabs-->>User: ErrorResponse(errorMessage)
        else save succeeded
            ManagePrefabs->>PrefabUtility: SaveAsPrefabAsset(prefabContentsRoot, prefabPath, saved)
            PrefabUtility-->>ManagePrefabs: saved = true
            ManagePrefabs->>PrefabStage: ClearDirtiness()
            ManagePrefabs->>AssetDatabase: SaveAssets()
            ManagePrefabs->>AssetDatabase: Refresh()
            ManagePrefabs->>PrefabStage: CloseStage()
            ManagePrefabs-->>User: SuccessResponse(Prefab stage closed)
        end
    end
Loading

Class diagram for updated ManagePrefabs prefab-stage save workflow

classDiagram
    class ManagePrefabs {
        <<static>>
        +object SavePrefabStage()
        +object ClosePrefabStage(bool saveBeforeClose)
        -static bool TrySavePrefabStage(PrefabStage prefabStage, string prefabPath, string errorMessage)
    }

    class PrefabStage {
        +string assetPath
        +Object prefabContentsRoot
        +Scene scene
        +void ClearDirtiness()
    }

    class PrefabUtility {
        +static void SaveAsPrefabAsset(Object prefabContentsRoot, string prefabPath, bool saved)
    }

    class AssetDatabase {
        +static void SaveAssets()
        +static void Refresh()
    }

    ManagePrefabs ..> PrefabStage : uses
    ManagePrefabs ..> PrefabUtility : uses
    ManagePrefabs ..> AssetDatabase : uses
Loading

File-Level Changes

Change Details Files
Fix prefab-stage save behavior to write prefab contents back to the prefab asset instead of the preview scene.
  • Update the save_prefab_stage command to delegate saving to a shared helper rather than marking and saving the prefab stage scene directly.
  • Change the save response payload to always report a successful save when the helper returns true, including the prefab asset path in the data.
  • Improve error handling for save_prefab_stage so failures return descriptive error messages instead of generic scene-save errors.
MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs
Share prefab-stage save workflow between explicit save and close-with-save flows.
  • Add a private TrySavePrefabStage helper that resolves the prefab asset path, validates prefabContentsRoot, writes it via PrefabUtility.SaveAsPrefabAsset, and synchronizes AssetDatabase state.
  • Refactor close_prefab_stage(saveBeforeClose: true) to call the shared TrySavePrefabStage helper instead of SavePrefabStage and to surface any save error via ErrorResponse.
  • Ensure prefab stage dirtiness is cleared after a successful save and asset database is saved and refreshed.
MCPForUnity/Editor/Tools/Prefabs/ManagePrefabs.cs
Add regression tests to validate prefab-stage save and close-with-save persistence.
  • Introduce SavePrefabStage_PersistsPrefabContentChanges to verify save_prefab_stage persists newly added child objects to the prefab asset and reports the correct prefab path.
  • Introduce ClosePrefabStage_SaveBeforeClose_PersistsChanges to ensure close_prefab_stage with saveBeforeClose closes the stage and persists added children to the prefab asset.
  • Extract an AssertOpenPrefabStage helper to reduce duplication when opening a prefab stage in tests.
TestProjects/UnityMCPTests/Assets/Tests/EditMode/Tools/ManagePrefabsStageTests.cs

Assessment against linked issues

Issue Objective Addressed Explanation
#1055 Update save_prefab_stage so that prefab-stage edits are saved to the prefab asset (using the prefab asset workflow) instead of attempting to save the prefab preview scene.
#1055 Ensure close_prefab_stage(saveBeforeClose: true) uses the same prefab-stage save workflow so that prefab content changes are persisted when closing the prefab stage with save-before-close.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Author

Version note: I validated this fix in the repo’s Unity 2021.3.45f2 test project. Based on Unity’s docs, the prefab-asset save path via PrefabUtility.SaveAsPrefabAsset(...) appears stable across 2021.3 and 6000.0 as well, so this does not look like a 2021-only issue. That said, I have not personally run this branch in newer editor versions, so a quick maintainer sanity-check on 2022.3/6000.x would still be valuable.

@jacklaplante jacklaplante marked this pull request as ready for review April 11, 2026 18:00
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

save_prefab_stage fails when saving prefab preview scenes

1 participant