stride3d/stride · error · InvalidOperationException
Invalid state for
Error message
Invalid state for {resource.CommandListFenceValue} What it means
After resolving the updating command list, mapping a Staging resource requires a recorded CommandListFenceValue to wait on. If it is null, Stride's internal state is inconsistent (no fence value was recorded for the resource) and it throws InvalidOperationException including the null value in the message.
Solutions
- Ensure staging resources are only updated through standard APIs (SetData/GetData) so fence values are recorded
- Check for Stride version regressions around staging mapping and update to a fixed release
- Avoid manually resetting/clearing resource.UpdatingCommandList or CommandListFenceValue state
Defensive patterns
Strategy: try-catch
Try / catch
try { cmdList.MapSubResource(staging, 0, MapMode.Read); } catch (InvalidOperationException ex) when (ex.Message.StartsWith("Invalid state for")) { /* treat as engine bug: recreate staging resource or file an issue */ } Prevention
- Update staging resources only via standard SetData/GetData APIs
- Do not manually mutate resource.UpdatingCommandList / CommandListFenceValue
- Keep Stride up to date; report occurrences with a reproduction
When it happens
Trigger: Mapping a Staging resource whose CommandListFenceValue was never set because the update path did not record a fence value (internal state bug or resource updated before the device fence was established).
Common situations: Engine-internal invariant breakage when mixing low-level resource updates with custom command list management; hitting the message with 'Invalid state for ' (empty) because the value is null.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- CommandList updating the staging resource has not been…
- AHardwareBuffer import requires…
- All should have hashsets associated to them
- argumentsBuffer
- Bound render targets
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/017a9b55645c4972.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs:1602
// updated in a previous command list which hasn't be finished yet
|| (resource.CommandListFenceValue is not null && !GraphicsDevice.CommandListFence.IsFenceCompleteInternal(resource.CommandListFenceValue.Value)))
{
// User told us not to wait, return right away
if (doNotWait)
{
return new MappedResource(resource, subResourceIndex, dataBox: default);
}
if (resource.UpdatingCommandList == this)
// Need to flush? (check if part of current command list)
// resource.CommandListFenceValue should be set after
FlushInternal(false);
else if (resource.UpdatingCommandList is not null)
// Another command list updated this resource, but it's not been submitted (otherwise it would be stored in resource.CommandListFenceValue
throw new InvalidOperationException("CommandList updating the staging resource has not been submitted");
if (resource.CommandListFenceValue is null)
throw new InvalidOperationException($"Invalid state for {resource.CommandListFenceValue}");
GraphicsDevice.CommandListFence.WaitForFenceCPUInternal(resource.CommandListFenceValue.Value);
// We're now up to date, remove command list fence value (if any)
resource.CommandListFenceValue = null;
}
}
// Also make sure all copy queues are done
// (important for all cases, since it uploads initial data and also set resource barrier)
if (resource.CopyFenceValue.HasValue)
{
GraphicsDevice.CopyFence.WaitForFenceCPUInternal(resource.CopyFenceValue.Value);
resource.CopyFenceValue = null;
}
void* mappedMemory;
GraphicsDevice.NativeDeviceApi.vkMapMemory(GraphicsDevice.NativeDevice, resource.NativeMemory, (ulong) offsetInBytes, (ulong) lengthInBytes, VkMemoryMapFlags.None, &mappedMemory);View on GitHub (pinned to 96fad776d2)