{"record":{"id":"ba2d773bbbf16202","repo":"stride3d/stride","slug":"commandlist-updating-the-staging-resource-has-not-been-ba2d77","errorCode":null,"errorMessage":"CommandList updating the staging resource has not been submitted","messagePattern":"CommandList updating the staging resource has not been submitted","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs","lineNumber":1599,"sourceCode":"                if (\n                    // used in command list which hasn't be submitted yet? (only valid if our own, checked later)\n                    resource.UpdatingCommandList is not null\n                    // updated in a previous command list which hasn't be finished yet\n                    || (resource.CommandListFenceValue is not null && !GraphicsDevice.CommandListFence.IsFenceCompleteInternal(resource.CommandListFenceValue.Value)))\n                {\n                    // User told us not to wait, return right away\n                    if (doNotWait)\n                    {\n                        return new MappedResource(resource, subResourceIndex, dataBox: default);\n                    }\n\n                    if (resource.UpdatingCommandList == this)\n                        // Need to flush? (check if part of current command list)\n                        // resource.CommandListFenceValue should be set after\n                        FlushInternal(false);\n                    else if (resource.UpdatingCommandList is not null)\n                        // Another command list updated this resource, but it's not been submitted (otherwise it would be stored in resource.CommandListFenceValue\n                        throw new InvalidOperationException(\"CommandList updating the staging resource has not been submitted\");\n\n                    if (resource.CommandListFenceValue is null)\n                        throw new InvalidOperationException($\"Invalid state for {resource.CommandListFenceValue}\");\n\n                    GraphicsDevice.CommandListFence.WaitForFenceCPUInternal(resource.CommandListFenceValue.Value);\n\n                    // We're now up to date, remove command list fence value (if any)\n                    resource.CommandListFenceValue = null;\n                }\n            }\n\n            // Also make sure all copy queues are done\n            // (important for all cases, since it uploads initial data and also set resource barrier)\n            if (resource.CopyFenceValue.HasValue)\n            {\n                GraphicsDevice.CopyFence.WaitForFenceCPUInternal(resource.CopyFenceValue.Value);\n                resource.CopyFenceValue = null;\n            }","sourceCodeStart":1581,"sourceCodeEnd":1617,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs#L1581-L1617","documentation":"When mapping a Staging resource on Vulkan, Stride must wait for the command list that last updated it to be submitted. If another (or this) command list updated the resource but its submissions are pending and it is not this command list, Stride cannot safely wait and throws InvalidOperationException.","triggerScenarios":"Calling MapSubResource/Map on a Staging texture or buffer whose UpdatingCommandList differs from the calling command list and has not been submitted; interleaving updates from multiple command lists without submitting between them.","commonSituations":"Using two command lists to fill and then read one staging texture; forgetting to call GraphicsDevice.CommandList flush/submit before mapping from another list.","solutions":["Submit/flush the updating command list before mapping from a different command list (call Flush on the updater)","Update and map the staging resource from the same command list","Use GraphicsDevice.CommandList (the default) for staging uploads so updates and maps are ordered"],"exampleFix":"// before\nstagingUpdaterCmdList.TextureData.SetData(...);\nmainCmdList.MapSubResource(stagingTex, ...); // updater not submitted\n// after\nstagingUpdaterCmdList.Flush();\nmainCmdList.MapSubResource(stagingTex, ...);","handlingStrategy":"try-catch","validationCode":"if (stagingResource.UpdatingCommandList != null && stagingResource.UpdatingCommandList != currentCmdList)\n    stagingResource.UpdatingCommandList.Flush();","typeGuard":null,"tryCatchPattern":"try { cmdList.MapSubResource(staging, 0, MapMode.Read); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"not been submitted\")) { updatingList.Flush(); /* retry */ }","preventionTips":["Always Flush/Submit the command list that updated a staging resource before mapping it elsewhere","Use a single command list for staging updates and reads","Keep staging upload/read paths on GraphicsDevice.CommandList"],"tags":["vulkan","staging-resource","command-list-sync"],"backgroundTag":"invalid-state-transition","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}