{"record":{"id":"73971e72305f6c47","repo":"stride3d/stride","slug":"commandlist-updating-the-staging-resource-has-not-been","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/Direct3D12/CommandList.Direct3D12.cs","lineNumber":2286,"sourceCode":"            {\n                // Need to wait?\n                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                    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(wait: false);\n                    else if (resource.UpdatingCommandList is not null)\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":2268,"sourceCodeEnd":2304,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs#L2268-L2304","documentation":"Before the CPU waits on a fence for a staging resource, Map verifies ownership of the last update. If another CommandList is currently updating the resource and that list has not been submitted (flushed), the code cannot safely wait, so it throws InvalidOperationException('CommandList updating the staging resource has not been submitted').","triggerScenarios":"Mapping a staging resource from one CommandList while resource.UpdatingCommandList points to a different, unsubmitted CommandList — i.e. data was recorded for upload on another command list but Flush/Submit hasn't been called on it.","commonSituations":"Recording updates on a background/secondary command list, then mapping the resource from the main list before submitting; interleaving Update on one list with Map on another within the same frame.","solutions":["Submit/Flush the command list that performed the Update (its.UpdatingCommandList flush) before mapping the resource from another list.","Map the staging resource from the same command list that updated it, or after that list has been submitted and the fence signaled.","Reorder code so Update and subsequent Map happen on the same command list in one submission.","Ensure the engine lifecycle sets UpdatingCommandList back to null after submission if you manage resources manually."],"exampleFix":"// before\nsecondaryCommandList.Update(stagingTexture, data);\ncommandList.Map(stagingTexture, MapMode.Read, 0); // throws: secondary not submitted\n// after\nsecondaryCommandList.Update(stagingTexture, data);\nsecondaryCommandList.Flush();\ncommandList.Map(stagingTexture, MapMode.Read, 0);","handlingStrategy":"try-catch","validationCode":"var updater = resource.UpdatingCommandList;\nif (updater is not null && updater != commandList)\n    updater.Flush(); // submit before mapping from another list","typeGuard":null,"tryCatchPattern":"try { commandList.Map(stagingResource, MapMode.Read, 0); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"has not been submitted\"))\n{ resource.UpdatingCommandList?.Flush(); /* retry */ }","preventionTips":["Submit the command list that updated a staging resource before mapping it elsewhere.","Keep Update and Map of a staging resource on the same command list when possible.","Avoid interleaving staging-resource updates across multiple command lists within a frame."],"tags":["direct3d12","graphics","fence","synchronization"],"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"}