Skip to content

Fix client crash: lazy CategoryIcon recipe-viewer wrapper (JEI runtime accessed during RegisterEvent)#5115

Open
ascorblack wants to merge 1 commit into
GregTechCEu:1.21from
ascorblack:fix/lazy-category-icon
Open

Fix client crash: lazy CategoryIcon recipe-viewer wrapper (JEI runtime accessed during RegisterEvent)#5115
ascorblack wants to merge 1 commit into
GregTechCEu:1.21from
ascorblack:fix/lazy-category-icon

Conversation

@ascorblack

Copy link
Copy Markdown

What

Fixes a client crash on world-independent startup when JEI is installed (and EMI is not): CategoryIcon constructors run during the RegisterEvent dispatch (GTRecipeCategories.init() inside CommonProxy.onRegister) and immediately call GTJEIPlugin.getRuntime(), which does not exist yet.

The resulting ExceptionInInitializerError aborts onRegister midway, so GTDataComponents.DATA_COMPONENTS never registers, and item registration then dies with:

java.lang.NullPointerException: Trying to access unbound value: ResourceKey[minecraft:data_component_type / gtceu:data_item]
	(while registering gtceu:data_stick)

Implementation Details

CategoryIcon now stores the raw ResourceLocation/ItemStack and resolves the EMI/JEI wrapper lazily on the first get() call — by then the recipe-viewer runtime exists. Behavior for EMI (which was safe eagerly) is unchanged apart from the deferral.

AI Usage

  • Yes AI driven tools were used for this pull request.

Agent Used

Claude Code (Claude Fable 5)

Agent Usage Description

The agent diagnosed the crash from our modpack's crash report, traced the eager getRuntime() call, and wrote the lazy-resolution patch and this PR text. The diff was reviewed by the submitter before opening.

Outcome

Client starts normally with JEI-only recipe viewer setups on 1.21 HEAD.

How Was This Tested

Reproduced the crash in our 1.21.1 pack (JEI 19.38, no EMI) on a build of 1.21 HEAD (1023cb75); with this patch applied the client boots and GT items/data components register normally. Dedicated server was unaffected before and after (the JEI wrapper path is never taken there).

Potential Compatibility Issues

None expected — get() callers receive the same wrapper objects, just created on first use instead of at registration time.

CategoryIcon constructors run during RegisterEvent dispatch
(GTRecipeCategories.init in CommonProxy.onRegister). With JEI (no EMI)
the JeiCallWrapper immediately calls GTJEIPlugin.getRuntime(), which
does not exist yet -> ExceptionInInitializerError aborts onRegister,
GTDataComponents never registers, and item registration crashes with
'Trying to access unbound value: gtceu:data_item' (data_stick).

Defer wrapper creation to the first get() call, when the viewer
runtime is available.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ascorblack ascorblack requested a review from a team as a code owner July 15, 2026 05:35
@github-actions github-actions Bot added the 1.21 label Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant