{"record":{"id":"2eabdff54521c6f6","repo":"Unity-Technologies/UnityCsReference","slug":"cannot-build-asset-bundles-while-a-build-is-in-pro","errorCode":null,"errorMessage":"Cannot build asset bundles while a build is in progress.","messagePattern":"Cannot build asset bundles while a build is in progress\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"Editor/Mono/BuildPipeline/BuildPipeline.bindings.cs","lineNumber":760,"sourceCode":"        {\n            if (buildParameters.targetPlatform == 0 || buildParameters.targetPlatform == BuildTarget.NoTarget)\n            {\n                buildParameters.targetPlatform = EditorUserBuildSettings.activeBuildTarget;\n\n                // Note: subtarget is associated with multiple enums, and 0 may have a specific meaning,\n                // so we only auto-set it when the target is also coming from the build settings\n                buildParameters.subtarget = EditorUserBuildSettings.GetActiveSubtargetFor(buildParameters.targetPlatform);\n            }\n\n            // For Standalone platforms, the Default subtarget means to use the current active one\n            if (GetBuildTargetGroup(buildParameters.targetPlatform) == BuildTargetGroup.Standalone &&\n                (StandaloneBuildSubtarget)buildParameters.subtarget == StandaloneBuildSubtarget.Default)\n            {\n                buildParameters.subtarget = EditorUserBuildSettings.GetActiveSubtargetFor(buildParameters.targetPlatform);\n            }\n\n            if (isBuildingPlayer)\n                throw new InvalidOperationException(\"Cannot build asset bundles while a build is in progress.\");\n\n            if (!System.IO.Directory.Exists(buildParameters.outputPath))\n                throw new ArgumentException(\"The output path \\\"\" + buildParameters.outputPath + \"\\\" doesn't exist\");\n\n            return BuildAssetBundlesInternal(buildParameters);\n        }\n\n        [NativeMethod(ThrowsException = true)]\n        private static extern AssetBundleManifest BuildAssetBundlesInternal(BuildAssetBundlesParameters buildParameters);\n\n        [FreeFunction(\"GetPlayerDataCache\")]\n        internal static extern string GetDataCacheForBuildTarget(BuildTarget target, int subtarget);\n\n        [FreeFunction(\"GetPlayerDataSessionId\")]\n        internal static extern string GetSessionIdForBuildTarget(BuildTarget target, int subtarget);\n\n        [FreeFunction(\"GetDataBuildDirtyInfoPath\")]\n        internal static extern string GetBuildDirtyInfoForBuildTarget(BuildTarget target, int subtarget);","sourceCodeStart":742,"sourceCodeEnd":778,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/BuildPipeline/BuildPipeline.bindings.cs#L742-L778","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\npublic void OnPostprocessBuild(BuildReport report)\n{\n    BuildPipeline.BuildAssetBundles(\"Bundles\", BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);\n}\n\n// after\npublic void OnPostprocessBuild(BuildReport report)\n{\n    // Defer to after the current build finishes\n    EditorApplication.delayCall += () =>\n    {\n        if (!BuildPipeline.isBuildingPlayer)\n            BuildPipeline.BuildAssetBundles(\"Bundles\", BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);\n    };\n}","handlingStrategy":"validation","validationCode":"void BuildAssetBundlesSafely(string outputPath, BuildAssetBundleOptions options, BuildTarget target)\n{\n    if (BuildPipeline.isBuildingPlayer)\n    {\n        Debug.LogWarning(\"Build already in progress; deferring AssetBundle build.\");\n        return;\n    }\n    BuildPipeline.BuildAssetBundles(outputPath, options, target);\n}\n\n// Or schedule after current build:\nif (BuildPipeline.isBuildingPlayer)\n    EditorApplication.delayCall += () => BuildAssetBundlesSafely(outputPath, options, target);\nelse\n    BuildPipeline.BuildAssetBundles(outputPath, options, target);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["unity","build-pipeline","asset-bundles","concurrent-build","build-lock"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}