Skip to content

fix(gotr): guard altar renderable cast to DynamicObject (1.5.10) - #636

Merged
chsami merged 1 commit into
developmentfrom
claude/err-gotr-altar-renderable-dynamicobject-cast
Oct 15, 2026
Merged

chsami merged 1 commit into
developmentfrom
claude/err-gotr-altar-renderable-dynamicobject-cast

Conversation

@chsami

@chsami chsami commented Oct 15, 2026

Copy link
Copy Markdown
Owner

Problem

Client error telemetry group 1280 (GotrPlugin 1.5.9, Microbot 2.6.30): 2 occurrences across 1 report, first seen 2026-10-12, last seen 2026-10-12.

java.lang.ClassCastException: class cc cannot be cast to class net.runelite.api.DynamicObject
  at GotrScript.lambda$getAvailableAltars$19:748
  at GotrScript.getAvailableAltars:758
  at GotrScript.lambda$enterAltar$14:409
  at Global.sleepUntil:176
  at GotrScript.enterAltar:409

Root cause

GotrScript.getAvailableAltars filters guardian altars by casting x.getRenderable() to DynamicObject (twice) with no type check. When an altar's renderable is a plain Model (an idle altar with no animation), the cast throws and breaks altar selection inside enterAltar's sleepUntil loop.

Change

  • New package-private static helper GotrScript.isActiveAltarRenderable(Renderable): returns false unless the renderable is a DynamicObject, reads getAnimation() once, and returns animation != null && animation.getId() == 9363.
  • The filter lambda calls this helper in place of the two unchecked casts. A non-DynamicObject renderable is treated as inactive, which matches the existing null-animation branch.
  • GotrPlugin version 1.5.9 -> 1.5.10.

Validation

  • New GotrAltarRenderableTest (5 cases): plain Model, null, DynamicObject with no animation, different animation id, active id 9363.
  • ./gradlew test -PpluginList=GotrPlugin --tests 'net.runelite.client.plugins.microbot.gotr.*' --tests 'PluginManifestVersionTest': BUILD SUCCESSFUL (GotrAltarRenderableTest 5/5, GotrPluginRoundEventTest 3/3, GotrPortalClockTest 7/7, PluginManifestVersionTest 1/1).
  • ./gradlew build -x test -PpluginList=GotrPlugin: BUILD SUCCESSFUL.

Known gaps

  • Not exercised live in a GOTR round; validated by unit tests against the exact failing type path.
  • Out of scope: MixologyScript.java:398 and :464 check instanceof DynamicObject but call getAnimation().getId() without a null check (possible NPE). Separate defect.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV

getAvailableAltars cast every altar renderable to DynamicObject, throwing
ClassCastException when the renderable is a plain Model. Check the type
first and read the animation once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
@chsami
chsami merged commit ba968d9 into development Oct 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant