Skip to content

fix(MahoganyHomes): skip hotspots beyond home object count in getFixableObjects (0.0.16) - #650

Merged
chsami merged 1 commit into
developmentfrom
claude/err-mahoganyhomes-fixable-objects-hotspot-index-oob
Oct 17, 2026
Merged

chsami merged 1 commit into
developmentfrom
claude/err-mahoganyhomes-fixable-objects-hotspot-index-oob

Conversation

@chsami

@chsami chsami commented Oct 17, 2026

Copy link
Copy Markdown
Owner

Problem

Client error telemetry (ScriptErrorGroups group id 2522: 2 hits from 1 report, MahoganyHomesPlugin 0.0.13, client 2.6.33) shows the Mahogany Homes script loop crashing:

java.lang.ArrayIndexOutOfBoundsException: Index 7 out of bounds for length 7
  at MahoganyHomesScript.lambda$getFixableObjects$1:78
  at MahoganyHomesScript.getFixableObjects:79
  at MahoganyHomesScript.fix:149
  at MahoganyHomesScript.lambda$run$0:57

Each throw stops the whole loop iteration, including fix, finish, getNewContract, bank and walkToHome.

Root cause

getFixableObjects() maps each broken Hotspot to hotspotObjects.objects[hotspot.ordinal()] and never checks the array length. Hotspot has 8 values (varbits 10554..10561), but some homes have fewer objects: ROSS, LARRY, NORMAN, TAU, BARBARA and LEELA have 7, and SARAH has 6. When hotspot 8's varbit reads broken at a 7-object home, the lookup indexes past the end of the array. The varbit can read broken because a value is left over from the previous contract or lags behind the home change. The bug is still present on development (0.0.15).

Change

  • The ID lookup moves into a package-private static helper, getFixableObjectIds(List<Hotspot>, HotspotObjects). It skips any hotspot whose ordinal is >= hotspotObjects.objects.length before indexing, and getFixableObjects() now calls it. All three callers (fix x2, readyFurniture) go through this helper.
  • MahoganyHomesPlugin version bumped from 0.0.15 to 0.0.16.
  • Three unit tests added to MahoganyHomesScriptTest:
    • all 8 hotspots on ROSS (7 objects) give 7 IDs
    • hotspots 1/7/8 on SARAH (6 objects) give only the first object's ID
    • all 8 hotspots on JESS (8 objects) give 8 IDs

Validation

  • ./gradlew test --tests '*mahoganyhomez.MahoganyHomesScriptTest' --tests '*PluginManifestVersionTest' -PpluginList=MahoganyHomesPlugin passes: 7/7 and 1/1 tests.
  • With the bounds filter temporarily removed, the ROSS and SARAH tests fail (2 of 7), so the new tests catch the bug.
  • I did not test this live in game.

Known gaps

  • Hotspot.isEverythingFixed() and MahoganyHomesPlugin.getCompletedCount() still loop over all 8 hotspots without knowing which home is current. This throws no exception: if hotspot 8 reads broken at a 7-object home, fix() now logs "No fixable objects found", and finish() waits for the varbit to clear. Before this fix, the same state crashed every tick. If that state turns out to last, the follow-up would be a home-aware getBrokenHotspots(HotspotObjects) / isEverythingFixed(HotspotObjects). Telemetry so far suggests the state is short-lived.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV

…bleObjects (0.0.16)

getFixableObjects indexed HotspotObjects.objects by Hotspot ordinal without a
bounds check, so a broken hotspot 8 varbit at a 7-object home (or 7/8 at
SARAH) threw ArrayIndexOutOfBoundsException and aborted the script loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
@chsami
chsami merged commit 1445d2a into development Oct 17, 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