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
- Check BuildPipeline.isBuildingPlayer before calling BuildAssetBundles and defer the call until the current build completes.
- Move the BuildAssetBundles call out of any IPreprocessBuildWithReport / IPostprocessBuildWithReport callback into a separate build step.
- 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
- Never call BuildAssetBundles from within IPreprocessBuildWithReport or IPostprocessBuildWithReport callbacks.
- Always check BuildPipeline.isBuildingPlayer before issuing a build.
- Use EditorApplication.delayCall to defer build operations from post-build callbacks.
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
- AssetBundleBuild cannot be null.
- The output path "{buildParameters.outputPath}" doesn't exist
- Scene path "{0}" contains invalid directory separators.
- The build target does not support build appending.
- The build cannot be appended.
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/2eabdff54521c6f6.
Report an issue: GitHub.