diff --git a/apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx b/apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx index b061cf091..033931eb8 100644 --- a/apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx +++ b/apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx @@ -726,6 +726,20 @@ function ResourceReferenceEditor({ if (initialDraftAppliedRef.current || !initialContent) { return; } + // Manifest assets can arrive after the initial editor mount. Do not mark the + // draft as applied while resource references still have no lookup table; + // otherwise the later assetsById update cannot restore those references. + const hasUnresolvedResourceReference = initialContent.some( + (part) => + part.type === 'agc_resource_reference' && + !assetsById.has(part.resourceId), + ); + if (hasUnresolvedResourceReference && assetsById.size === 0) { + return; + } + // TODO: let the Lexical resource node resolve its asset label from the + // manifest itself, so unresolved references can remain as nodes while the + // manifest loads instead of waiting in this effect. initialDraftAppliedRef.current = true; editor.update(() => { applyContentToRoot(initialContent, assetsById);