Unity-Technologies/UnityCsReference · error · InvalidOperationException

Cannot build asset bundles while a build is in progress.

Error message

Cannot build asset bundles while a build is in progress.

What it means

Thrown by BuildAssetBundles when BuildPipeline.isBuildingPlayer is true, meaning a player build or another asset bundle build is already running. Unity's build system uses a global lock and does not support concurrent build operations in the same editor process.

Source

Thrown at Editor/Mono/BuildPipeline/BuildPipeline.bindings.cs:760

        {
            if (buildParameters.targetPlatform == 0 || buildParameters.targetPlatform == BuildTarget.NoTarget)
            {
                buildParameters.targetPlatform = EditorUserBuildSettings.activeBuildTarget;

                // Note: subtarget is associated with multiple enums, and 0 may have a specific meaning,
                // so we only auto-set it when the target is also coming from the build settings
                buildParameters.subtarget = EditorUserBuildSettings.GetActiveSubtargetFor(buildParameters.targetPlatform);
            }

            // For Standalone platforms, the Default subtarget means to use the current active one
            if (GetBuildTargetGroup(buildParameters.targetPlatform) == BuildTargetGroup.Standalone &&
                (StandaloneBuildSubtarget)buildParameters.subtarget == StandaloneBuildSubtarget.Default)
            {
                buildParameters.subtarget = EditorUserBuildSettings.GetActiveSubtargetFor(buildParameters.targetPlatform);
            }

            if (isBuildingPlayer)
                throw new InvalidOperationException("Cannot build asset bundles while a build is in progress.");

            if (!System.IO.Directory.Exists(buildParameters.outputPath))
                throw new ArgumentException("The output path \"" + buildParameters.outputPath + "\" doesn't exist");

            return BuildAssetBundlesInternal(buildParameters);
        }

        [NativeMethod(ThrowsException = true)]
        private static extern AssetBundleManifest BuildAssetBundlesInternal(BuildAssetBundlesParameters buildParameters);

        [FreeFunction("GetPlayerDataCache")]
        internal static extern string GetDataCacheForBuildTarget(BuildTarget target, int subtarget);

        [FreeFunction("GetPlayerDataSessionId")]
        internal static extern string GetSessionIdForBuildTarget(BuildTarget target, int subtarget);

        [FreeFunction("GetDataBuildDirtyInfoPath")]
        internal static extern string GetBuildDirtyInfoForBuildTarget(BuildTarget target, int subtarget);

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Check BuildPipeline.isBuildingPlayer before calling BuildAssetBundles and defer the call until the current build completes.
  2. Move the BuildAssetBundles call out of any IPreprocessBuildWithReport / IPostprocessBuildWithReport callback into a separate build step.
  3. Serialize build operations through a queue that awaits EditorApplication.isCompiling and isBuildingPlayer before issuing the next build.

Example fix

// before
public void OnPostprocessBuild(BuildReport report)
{
    BuildPipeline.BuildAssetBundles("Bundles", BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
}

// after
public void OnPostprocessBuild(BuildReport report)
{
    // Defer to after the current build finishes
    EditorApplication.delayCall += () =>
    {
        if (!BuildPipeline.isBuildingPlayer)
            BuildPipeline.BuildAssetBundles("Bundles", BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
    };
}
Defensive patterns

Strategy: validation

Validate before calling

void BuildAssetBundlesSafely(string outputPath, BuildAssetBundleOptions options, BuildTarget target)
{
    if (BuildPipeline.isBuildingPlayer)
    {
        Debug.LogWarning("Build already in progress; deferring AssetBundle build.");
        return;
    }
    BuildPipeline.BuildAssetBundles(outputPath, options, target);
}

// Or schedule after current build:
if (BuildPipeline.isBuildingPlayer)
    EditorApplication.delayCall += () => BuildAssetBundlesSafely(outputPath, options, target);
else
    BuildPipeline.BuildAssetBundles(outputPath, options, target);

Prevention

When it happens

Trigger: Calling BuildPipeline.BuildAssetBundles while a BuildPipeline.BuildPlayer call is in progress, or calling BuildAssetBundles from within a build callback (IPreprocessBuildWithReport, IPostprocessBuildWithReport) that fires during an active build.

Common situations: A build post-processor attempts to build asset bundles as part of the player build pipeline, an editor script triggered by ExecuteAlways calls BuildAssetBundles during a player build, or a build queue system issues overlapping build commands without synchronization.

Related errors


AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13). Data as JSON: /api/errors/2eabdff54521c6f6. Report an issue: GitHub.