Some of our automated LoadMap tests are failing randomly due to missing shader assets. We used a coding agent to comb through the run and build logs, and made some diagnostic runs, and it identified a potential issue with the shader library pruning. We want to verify if this is a legit issue/fix and not just a hallucination on the AI’s part.
Proposed fix
In FEditorShaderCodeArchive::UpdateOplogPackages(), when a committed package has no oplog data, mark it as referenced by both oplog and staging so the prune step cannot discard its shaders:
void FEditorShaderCodeArchive::UpdateOplogPackages(UE::Cook::Artifact::FUpdateOplogPackagesContext& Context)
{
...
for (TPair<FName, FShaderMapAssetAssociations::FAssociatedAssetData>& Pair : AssetMap.ViewAssets())
{
...
if (PackageName.IsNone())
{
...
}
else
{
const FOplogPackageData* OplogData = OplogPackages.Find(PackageName);
if (OplogData)
{
...
}
// ENGINE_MOD_BEGIN
else
{
// The package is neither in this cook's referenced set nor in the persistent oplog. Leaving the asset
// unreferenced here would cause Prune() to drop every shadermap associated with it, so the asset would
// silently lose its shaders in the deployed build. We cannot positively determine that the asset is
// stale (the oplog may be incomplete, e.g. for shader libraries seeded from a shared/source cache),
// so conservatively keep it referenced by both oplog and staging.
Pair.Value.bReferencedByOplog = true;
Pair.Value.bReferencedByStaging = true;
}
// ENGINE_MOD_END
}
}
}
The other fix it proposed is to set bIncrementalCookPruningEnabled to false, as the comment indicates it might be unstable.
Here’s the AI analysis of the issue:
Summary
In projects that use incremental cooking (-CookIncremental, IoStore/-ZenStore), a cook can produce a package whose materials reference shader maps that are absent from the published shader library. The cook itself reports no error; the failure only appears at runtime/package-validation time when the cooked assets are serialized and the missing hash is looked up.
Symptoms (runtime / packaged build log)
LogShaders: Error: Missing shader resource for hash ‘<HASH>’ for shader platform ‘PCD3D_SM6’
in the shader library while serializing asset <ASSET>
LogMaterial: Error: Tried to access an uncooked shader map ID in a cooked application. Material: <MATERIAL>
And in-game the material falls back to the default material. The affected assets are intermittent/rotating between cooks (not a fixed asset), which is the tell that this is a pruning/reference-tracking bug rather than a bad asset.
Note that the cook log shows no Failed to compile Material … error for these cases — the shaders compiled fine; they were simply pruned from the library after being cooked.
Root cause
During incremental cook, the shader library prune step decides which shader maps to keep based on oplog package reference data (FOplogPackageData::ReferenceType, default Unreferenced). FEditorShaderCodeArchive::UpdateOplogPackages() walks the committed packages for the platform and marks each package’s reference type.
When a package has no oplog entry (OplogData == nullptr), the else branch failed to mark the package as referenced. Such a package’s shaders were therefore treated as unreferenced by the prune step and were dropped from the archive, even though the package is committed and will be serialized in the cooked build. This matches the observed behavior: shaders referenced only by packages without oplog data vanish, and the affected set changes as the incremental oplog changes between builds.
Relevant code path:
FEditorShaderCodeArchive::InitializeReferenceTracking() — sets up tracking
FEditorShaderCodeArchive::UpdateOplogPackages() — assigns reference type per committed package
FEditorShaderCodeArchive::Prune() — removes shaders not referenced by oplog/staging
FOplogPackageData (CoreUObject/Public/Cooker/CookArtifact.h) — ReferenceType defaults to Unreferenced
[Attachment Removed]