# UE 5.8 – NNERuntimeBasicCpu: Conv1d/Conv2d crash when the convolved observation is a stateless layer

**URL:** <https://forums.unrealengine.com/t/ue-5-8-nneruntimebasiccpu-conv1d-conv2d-crash-when-the-convolved-observation-is-a-stateless-layer/2854803>\
**Category:** Programming & Scripting\
**Tags:** Reinforcement-Learning, bug, unreal-engine, Learning-Agents, bug-report\
**Created:** [November 12, 2026, 10:20pm UTC](https://forums.unrealengine.com/t/ue-5-8-nneruntimebasiccpu-conv1d-conv2d-crash-when-the-convolved-observation-is-a-stateless-layer/2854803 "2026-11-12T22:20:04Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![AdyTheQueen2020](https://d3kjluh73b9h9o.cloudfront.net/original/4X/2/8/5/28502927f1d97ba1051b3b47ccfe17233bf41ef0.png) [@AdyTheQueen2020](https://forums.unrealengine.com/u/AdyTheQueen2020)\
**Post date:** [November 12, 2026, 10:20pm UTC](https://forums.unrealengine.com/t/ue-5-8-nneruntimebasiccpu-conv1d-conv2d-crash-when-the-convolved-observation-is-a-stateless-layer/2854803/1 "2026-11-12T22:20:04Z")

</div>

## Summary

`FConv1dInstance::SetMaxBatchSize` and `FConv2dInstance::SetMaxBatchSize` call `SubLayerInstance->SetMaxBatchSize(MaxBatchSize)` unconditionally.

`ILayer::MakeInstance()` returns `nullptr` by default, so any stateless sub-layer has no instance and the call dereferences a null `TSharedPtr`. The editor asserts in `SharedPointer.h` (`IsValid()`, line 1133) as soon as the policy is created.

- **Engine version:** 5.8
- **File:** `Engine/Plugins/Experimental/NNERuntimeBasicCpu/Source/NNERuntimeBasicCpu/Private/NNERuntimeBasicCpuModel.cpp`
- **Affects:** Learning Agents, `SpecifyConv1dObservation` / `SpecifyConv2dObservation`

## Steps to reproduce

1. In a Learning Agents interactor, wrap a plain continuous observation in a 2D convolution:

```cpp
ULearningAgentsObservations::SpecifyConv2dObservation(
    Schema,
    ULearningAgentsObservations::SpecifyContinuousObservation(Schema, 12 * 24),
    FConv2dObservationParams(12, 24, 1, 8, 3, 2, 1));

```

1. Start training, or anything else that calls `ULearningAgentsPolicy::SetupPolicy`.
2. The editor crashes.

## Callstack

```auto
Assertion failed: IsValid() [SharedPointer.h] [Line: 1133]

UE::NNE::RuntimeBasic::Private::FConv2dInstance::SetMaxBatchSize()
UE::NNE::RuntimeBasic::Private::FSequenceLayerInstance::SetMaxBatchSize()
UE::NNE::RuntimeBasic::Private::FConcatLayerInstance::SetMaxBatchSize()
UE::NNE::RuntimeBasic::FModelInstanceCPU::SetInputTensorShapes()
UE::Learning::FNeuralNetworkInference::ReloadModelInstances()
UE::Learning::FNeuralNetwork::CreateInferenceObject()
ULearningAgentsPolicy::SetupPolicy()

```

## Cause

`FConv2dInstance`’s constructor stores `Conv2dLayer.SubLayer->MakeInstance()`, which is `nullptr` for a stateless layer:

```cpp
FConv2dInstance::FConv2dInstance(const FConv2dLayer& InConv2dLayer) : Conv2dLayer(InConv2dLayer)
{
    SubLayerInstance = Conv2dLayer.SubLayer->MakeInstance();
}

```

`SetMaxBatchSize` then uses it without a check:

```cpp
void FConv2dInstance::SetMaxBatchSize(const uint32 MaxBatchSize)
{
    SubLayerInstance->SetMaxBatchSize(MaxBatchSize); // null here
    SubLayerOutputBuffer.SetNumUninitialized(MaxBatchSize * Conv2dLayer.SubLayer->GetOutputSize(), EAllowShrinking::No);
}

```

Other wrapper layers in the same file already guard this case, for example the aggregate set layer:

```cpp
if (SubLayerInstance) { SubLayerInstance->SetMaxBatchSize(MaxBatchSize * AggregateSetLayer.MaxElementNum); }

```

`FConv1dInstance` has the same unguarded call.

## Suggested fix

Guard the call in both `FConv1dInstance::SetMaxBatchSize` and `FConv2dInstance::SetMaxBatchSize`:

```cpp
if (SubLayerInstance) { SubLayerInstance->SetMaxBatchSize(MaxBatchSize); }

```

## Verification

With this guard applied locally, the Conv2d observation above trains and runs for several hours without the crash.

Conv1d was patched the same way because the code is identical. We have not exercised it.
