Skip to content

Fix crashes introduced in MoP 5.5.4 (build 68016)#69

Closed
HydraxSkarrag wants to merge 15 commits into
Nevcairiel:masterfrom
HydraxSkarrag:fix/mop554-compat
Closed

Fix crashes introduced in MoP 5.5.4 (build 68016)#69
HydraxSkarrag wants to merge 15 commits into
Nevcairiel:masterfrom
HydraxSkarrag:fix/mop554-compat

Conversation

@HydraxSkarrag

Copy link
Copy Markdown

Summary

WoW Mists of Pandaria patch 5.5.4 (build 68016) introduced several Retail-backported API changes that cause the following errors on login/zone change:

  • attempt to index field 'db' (a nil value) in HideBlizzardFrames — triggered by ADDON_LOADED (Blizzard_ArenaUI) firing before PLAYER_LOGIN has run OnInitialize, so self.db is not yet set
  • attempt to index local 'frame' (a nil value) in hideBlizzardFrames — the legacy PartyMemberFrame1..N globals no longer exist in 5.5.4; _G[name] returns nil and gets passed into the loop
  • bad argument #2 to '?' (Usage: local success = self:SetStatusBarTexture(asset)) — 5.5.4 now rejects empty strings in SetStatusBarTexture; guard added
  • bad argument #1 to 'pairs' (table expected, got nil) in Combo:Update — when a combo-point module (e.g. Soul Shards) is configured as a bar, only .blocks is created, not .points; nil-guard added

Fixes

File Change
ShadowedUnitFrames.lua Early return in HideBlizzardFrames when self.db is nil
ShadowedUnitFrames.lua Skip nil frames in hideBlizzardFrames loop
modules/layout.lua Only call SetStatusBarTexture when path is non-empty
modules/basecombopoints.lua Guard frame[key].points before iterating

Tested on WoW Classic (MoP) 5.5.4.68016.

- Guard HideBlizzardFrames against nil self.db when called via
  ADDON_LOADED before PLAYER_LOGIN has run OnInitialize
- Skip nil frames in hideBlizzardFrames (old PartyMemberFrame1..N
  globals no longer exist in 5.5.4)
- Skip SetStatusBarTexture when mediaPath.statusbar is empty/nil;
  the updated API now rejects empty strings with a hard error
- Guard frame[key].points before pairs() in Combo:Update; bar-mode
  combo points (e.g. Soul Shards as bar) only create .blocks, not .points

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@HydraxSkarrag

Copy link
Copy Markdown
Author

Fix was done with Claude Code. 1 Prompt and all was working again. Changes are minimal and I think clear to understand.

@almx

almx commented Jun 5, 2026

Copy link
Copy Markdown

I have tested it and found some issues:

  • The target frame is borked when in an instance, for example a celestial dungeon. When targeting an enemy, it retains the name, health, buffs/debuffs etc. of the last friendly target you had and never updates when you go around killing enemies. Likewise, the target of target frame is also incorrect.
  • Hiding the blizzard cast bar and hiding party frames doesn't work

Some stack traces that get spammed a lot, thousands of times from just one dungeon run:

ShadowedUnitFrames/modules/auras.lua:548: attempt to index a nil value
[ShadowedUnitFrames/modules/auras.lua]:548: in function <ShadowedUnitFrames/modules/auras.lua:525>
[ShadowedUnitFrames/modules/auras.lua]:644: in function <ShadowedUnitFrames/modules/auras.lua:590>
[ShadowedUnitFrames/modules/auras.lua]:698: in function '?'
[ShadowedUnitFrames/modules/units.lua]:37: in function 'FullUpdate'
[ShadowedUnitFrames/modules/units.lua]:376: in function 'CheckUnitStatus'
[ShadowedUnitFrames/modules/units.lua]:232: in function <ShadowedUnitFrames/modules/units.lua:229>
[C]: in function 'Show'
[Blizzard_RestrictedAddOnEnvironment/SecureStateDriver.lua]:83: in function <...ard_RestrictedAddOnEnvironment/SecureStateDriver.lua:73>
[Blizzard_RestrictedAddOnEnvironment/SecureStateDriver.lua]:137: in function <...ard_RestrictedAddOnEnvironment/SecureStateDriver.lua:119>

ShadowedUnitFrames/modules/xp.lua:89: attempt to call a nil value
[ShadowedUnitFrames/modules/xp.lua]:89: in function 'UpdateRep'
[ShadowedUnitFrames/modules/xp.lua]:139: in function '?'
[ShadowedUnitFrames/modules/units.lua]:37: in function 'FullUpdate'
[ShadowedUnitFrames/modules/units.lua]:376: in function 'CheckUnitStatus'
[ShadowedUnitFrames/modules/units.lua]:615: in function <ShadowedUnitFrames/modules/units.lua:441>
[C]: in function 'SetAttribute'
[ShadowedUnitFrames/modules/units.lua]:965: in function 'LoadUnit'
[ShadowedUnitFrames/modules/units.lua]:1338: in function 'InitializeFrame'
[ShadowedUnitFrames/ShadowedUnitFrames.lua]:572: in function 'LoadUnits'
[ShadowedUnitFrames/ShadowedUnitFrames.lua]:89: in function 'OnInitialize'
[ShadowedUnitFrames/ShadowedUnitFrames.lua]:1222: in function <...aceShadowedUnitFrames/ShadowedUnitFrames.lua:1220>

- auras.lua: DebuffTypeColor.none no longer exists in 5.5.4; add
  hard fallback color {r=0.8,g=0,b=0} so typeless debuffs don't crash
- xp.lua: C_Reputation.GetWatchedFactionData is a Retail-only API;
  fall back to GetWatchedFactionInfo() on builds that lack it,
  building a compatible factionData table from the old return values
- ShadowedUnitFrames.lua: try both PlayerCastingBarFrame (new name)
  and CastingBarFrame (MoP name) so cast-bar hiding works on both builds

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@HydraxSkarrag

HydraxSkarrag commented Jun 6, 2026

Copy link
Copy Markdown
Author

Hi, I am not able to test this changes right now. But I provided you what Claude Code did here. See the message below. Hope this will help!


Thanks for testing! I've pushed a second commit to address the reported issues:

auras.lua:548 – spam crash in dungeons
DebuffTypeColor.none no longer exists in MoP 5.5.4. Added a hard fallback color {r=0.8, g=0, b=0} so typeless debuffs don't crash the frame.

xp.lua:89 – crash on load
C_Reputation.GetWatchedFactionData is a Retail-only API that doesn't exist in MoP 5.5.4. Added a fallback to the old GetWatchedFactionInfo() API, building a compatible factionData table from its return values.

Cast bar hiding not working
PlayerCastingBarFrame is the Retail/new name — in MoP 5.5.4 the frame is still called CastingBarFrame. The code now tries PlayerCastingBarFrame or CastingBarFrame so it works on both builds.


Regarding target frame not updating in instances: this sounds like a deeper event-registration or RegisterUnitWatch issue. More specific stack traces or error messages from that scenario would help narrow it down — do you have any Lua errors from when targeting an enemy in the dungeon?

New error report (1939x) showed auraType=nil and the lookup still
crashing - turns out DebuffTypeColor itself can be nil at the point
auras first render (likely loaded lazily by a different system addon
in this build), not just the .none entry. Guard both indexing levels
and keep the hard fallback color.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sfhb24

sfhb24 commented Jun 8, 2026

Copy link
Copy Markdown

I was trying your latest commit and getting this crash:

17x ShadowedUnitFrames/modules/units.lua:249: attempt to call a nil value
[ShadowedUnitFrames/modules/units.lua]:249: in function 'SetVisibility'
[ShadowedUnitFrames/modules/units.lua]:614: in function <ShadowedUnitFrames/modules/units.lua:441>
[C]: in function 'SetAttribute'
[ShadowedUnitFrames/modules/units.lua]:965: in function 'LoadUnit'
[ShadowedUnitFrames/modules/units.lua]:1338: in function 'InitializeFrame'
[ShadowedUnitFrames/ShadowedUnitFrames.lua]:283: in function 'LoadUnits'
[ShadowedUnitFrames/ShadowedUnitFrames.lua]:87: in function 'OnInitialize'
[ShadowedUnitFrames/ShadowedUnitFrames.lua]:953: in function <...aceShadowedUnitFrames/ShadowedUnitFrames.lua:951>

Frames are not loading at all anymore.

GetSpecialization() does not exist in this build, causing all frames
to fail loading entirely. Fall back to spec 1 so spec-gated modules
behave as if the player is in their primary spec.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@HydraxSkarrag

Copy link
Copy Markdown
Author

Fourth fix pushed — GetSpecialization() does not exist in MoP 5.5.4, causing all frames to fail loading entirely on startup.

17x ShadowedUnitFrames/modules/units.lua:249: attempt to call a nil value
[ShadowedUnitFrames/modules/units.lua]:249: in function 'SetVisibility'
...
[ShadowedUnitFrames/ShadowedUnitFrames.lua]:87: in function 'OnInitialize'

Fixed with a simple guard: GetSpecialization and GetSpecialization() or 1 — falls back to spec 1 so spec-gated modules behave as if the player is in their primary spec.

Everything is loading and functional again after this fix. Still testing further — will report back if more issues come up.

@sfhb24

sfhb24 commented Jun 8, 2026

Copy link
Copy Markdown

Also

3x ...aceShadowedUnitFrames/modules/indicators.lua:115: attempt to call a nil value
[ShadowedUnitFrames/modules/indicators.lua]:115: in function '?'
[ShadowedUnitFrames/modules/units.lua]:36: in function 'FullUpdate'
[ShadowedUnitFrames/modules/units.lua]:376: in function 'CheckUnitStatus'
[ShadowedUnitFrames/modules/units.lua]:231: in function <ShadowedUnitFrames/modules/units.lua:228>
[C]: in function 'Show'

UnitIsQuestBoss() no longer exists in this build, crashing the
indicators update on any unit frame shown.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@HydraxSkarrag

Copy link
Copy Markdown
Author

Another nil API: UnitIsQuestBoss() does not exist in MoP 5.5.4, crashing the indicators update on every unit frame shown.

3x ShadowedUnitFrames/modules/indicators.lua:115: attempt to call a nil value

Fixed with UnitIsQuestBoss and UnitIsQuestBoss(frame.unit) guard.

@sfhb24

sfhb24 commented Jun 9, 2026

Copy link
Copy Markdown

Still getting these 2:

112x ...faceShadowedUnitFrames/modules/highlight.lua:137: attempt to index global 'DebuffTypeColor' (a nil value)
[ShadowedUnitFrames/modules/highlight.lua]:137: in function 'Update'
[ShadowedUnitFrames/modules/highlight.lua]:193: in function '?'
[ShadowedUnitFrames/modules/units.lua]:214: in function <ShadowedUnitFrames/modules/units.lua:211>

83x ...aceShadowedUnitFrames/modules/indicators.lua:115: attempt to call a nil value
[ShadowedUnitFrames/modules/indicators.lua]:115: in function '?'
[ShadowedUnitFrames/modules/units.lua]:36: in function 'FullUpdate'
[ShadowedUnitFrames/modules/units.lua]:376: in function 'CheckUnitStatus'
[ShadowedUnitFrames/modules/units.lua]:231: in function <ShadowedUnitFrames/modules/units.lua:228>

Same issue as auras.lua - DebuffTypeColor global does not exist in
this build, crashing the highlight update whenever a unit has a debuff.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@HydraxSkarrag

Copy link
Copy Markdown
Author

Two more fixes:

highlight.lua:137DebuffTypeColor is nil (same root cause as auras.lua), crashing the highlight update whenever a unit has a debuff. Same guard pattern applied.

indicators.lua:115 (UnitIsQuestBoss) — the fix was already in the previous commit; if you're still seeing this one, please make sure you're on the latest commit.

Tested locally — unit frames are stable. Further in-game testing (dungeons, PvP, etc.) still ongoing.

- health.lua: guard DebuffTypeColor (nil in this build) when coloring
  health bar by dispellable debuff type
- soulshards.lua: replace all GetSpecialization() calls with local
  GetSpec() helper that falls back to 1 if the API doesn't exist;
  prevents crash for any Warlock player
- indicators.lua: guard GetArenaOpponentSpec + GetSpecializationInfoByID
  at both call sites (arena spec icon + LFD role via spec)
- units.lua: same guard for ArenaClassToken

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@HydraxSkarrag

Copy link
Copy Markdown
Author

Proactive batch fix for all remaining known-nil APIs in MoP 5.5.4:

  • health.luaDebuffTypeColor nil guard (same root cause as auras.lua / highlight.lua)
  • soulshards.luaGetSpecialization() called 6× without guard; added local GetSpec() helper that falls back to 1 — prevents crash for any Warlock
  • indicators.luaGetArenaOpponentSpec + GetSpecializationInfoByID guarded at both call sites (arena spec icon + LFD role lookup)
  • units.lua — same guard for ArenaClassToken

@sfhb24

sfhb24 commented Jun 9, 2026

Copy link
Copy Markdown

All the debuff coloring is falling back to the default red you added. Is there a way to fix the border colors to match the correct type again? For instance I had a red border around my raid frames for dispel-able debuffs.

…lors

DebuffTypeColor is nil in MoP 5.5.4 causing all debuff borders/highlights
to fall back to a hard-coded red. Instead, define the standard WoW debuff
type color table once in ShadowedUnitFrames.lua when the global is absent:
  Magic=blue, Curse=purple, Disease=brown, Poison=green, none/""=red

This allows auras.lua, highlight.lua and health.lua to use the correct
per-type colors again, and simplifies those guards back to their original
readable form.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@HydraxSkarrag

Copy link
Copy Markdown
Author

Fix: debuff border colors restored (Magic=blue, Curse=purple, Disease=brown, Poison=green)

The previous approach of falling back to a hard-coded red {r=0.8, g=0, b=0} was a workaround that lost all type-specific coloring. Proper fix: define the full DebuffTypeColor table once in ShadowedUnitFrames.lua when the global is absent, so all modules (auras.lua, highlight.lua, health.lua) can use the correct per-type colors as before — no more scattered guards needed.

New download link for testers: https://github.com/HydraxSkarrag/ShadowedUnitFrames/archive/refs/heads/fix/mop554-compat.zip

Blizzard replaced the DebuffTypeColor table with individual globals
(DEBUFF_TYPE_MAGIC_COLOR, DEBUFF_TYPE_CURSE_COLOR, etc.) in MoP 5.5.4.
Rebuild the table from those where available so the game's own colour
values are used. The classic defaults are kept as a last-resort fallback
only if those globals are also absent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@HydraxSkarrag

Copy link
Copy Markdown
Author

Fix: debuff border colors now use Blizzard's own colour values

The previous red fallback was a workaround. Root cause: Blizzard replaced the DebuffTypeColor table in MoP 5.5.4 with individual globals (DEBUFF_TYPE_MAGIC_COLOR, DEBUFF_TYPE_CURSE_COLOR, DEBUFF_TYPE_DISEASE_COLOR, DEBUFF_TYPE_POISON_COLOR, DEBUFF_TYPE_NONE_COLOR).

The fix (same approach as WeakAuras/LibDispel) rebuilds DebuffTypeColor from those new globals if the table is absent, with classic WoW defaults only as a last resort. Magic=blue, Curse=purple, Disease=brown, Poison=green — pulled from the game itself, not hardcoded.

Needs testing: raid frames with dispellable debuffs (Magic/Curse/Poison/Disease borders). We don't have a raid frames user on our end to verify.

Latest ZIP for testers: https://github.com/HydraxSkarrag/ShadowedUnitFrames/archive/refs/heads/fix/mop554-compat.zip

@sfhb24

sfhb24 commented Jun 10, 2026

Copy link
Copy Markdown

The color is working, but I don't think the filtering for "only show ones I can dispel" is (on raid frames). I was seeing blue magic as a shadow priest. Unless its counting mass dispel now (which it didn't, before)

@HydraxSkarrag

Copy link
Copy Markdown
Author

Follow-up on the Magic-debuff-highlight question for Shadow Priests:

The "can cure" detection (`modules/units.lua` ~line 1500) uses `IsPlayerSpell(spellID) or IsSpellKnown(spellID, true)` to decide if the player currently has access to a dispel (e.g. Mass Dispel = 32375 → "Magic" for Priests).

Since there were apparently no class/spell changes in 5.5.4, this is more likely an API behavior change: the retail spellbook rework (Class Tree vs Spec Tree, flattened spellbook) may cause `IsPlayerSpell`/`IsSpellKnown` to now return `true` for spells that exist anywhere in the class spellbook, regardless of whether the current spec can actually cast them — whereas previously it returned `false` for spec-locked spells.

Could a Shadow Priest run this in-game and report the result?
```
/run print("IsPlayerSpell:", IsPlayerSpell(32375), "IsSpellKnown:", IsSpellKnown(32375, true))
```

If both return `true` while on Shadow spec (where Mass Dispel shouldn't be usable), that confirms the API change and we'll need a more reliable check (e.g. `IsUsableSpell` or spec-based filtering).

@sfhb24

sfhb24 commented Jun 10, 2026

Copy link
Copy Markdown

I am an spriest....

/run print("IsPlayerSpell:", IsPlayerSpell(32375), "IsSpellKnown:", IsSpellKnown(32375, true))

Result:
IsPlayerSpell: true IsSpellKnown: false

IsPlayerSpell() now returns true for spells anywhere in the class
spellbook regardless of the current spec in MoP 5.5.4 (e.g. a Shadow
Priest reports IsPlayerSpell(32375) [Mass Dispel] as true, even though
it's not castable in that spec). This caused Magic debuffs to be
highlighted as curable for specs that can't actually dispel them.

IsSpellKnown(spellID) (player spellbook, no pet flag) correctly
reflects spec-gated availability and replaces the unreliable
IsPlayerSpell/IsSpellKnown(.., true) combo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@HydraxSkarrag

Copy link
Copy Markdown
Author

Confirmed and fixed — thanks for testing!

`IsPlayerSpell(32375)` (Mass Dispel) returns `true` even on Shadow spec, where it's not actually castable. This is the broken API in 5.5.4 (likely related to the retail spellbook rework where IsPlayerSpell now reflects "exists in class spellbook" rather than "usable in current spec").

Fix: replaced `IsPlayerSpell(spellID) or IsSpellKnown(spellID, true)` with just `IsSpellKnown(spellID)`, which correctly reflects spec-gated availability — this is the standard check other addons use for "can I currently cast this".

Magic debuffs should no longer be highlighted as curable for Shadow Priests after this update.

Latest ZIP for testers: https://github.com/HydraxSkarrag/ShadowedUnitFrames/archive/refs/heads/fix/mop554-compat.zip

@100mll

100mll commented Jun 10, 2026

Copy link
Copy Markdown

hm...
1.

7x ShadowedUnitFrames/modules/layout.lua:381: attempt to index a nil value [ShadowedUnitFrames/modules/layout.lua]:381: in function 'SetupBars' [ShadowedUnitFrames/modules/layout.lua]:142: in function 'Load' [ShadowedUnitFrames/modules/units.lua]:309: in function 'SetVisibility' [ShadowedUnitFrames/modules/units.lua]:614: in function <ShadowedUnitFrames/modules/units.lua:441> [C]: in function 'SetAttribute' [ShadowedUnitFrames/modules/units.lua]:965: in function 'LoadUnit' [ShadowedUnitFrames/modules/units.lua]:1338: in function 'InitializeFrame' [ShadowedUnitFrames/ShadowedUnitFrames.lua]:298: in function 'LoadUnits' [ShadowedUnitFrames/modules/units.lua]:1469: in function 'CheckPlayerZone' [ShadowedUnitFrames/modules/units.lua]:1531: in function <ShadowedUnitFrames/modules/units.lua:1522>

1x ShadowedUnitFrames/modules/auras.lua:659: attempt to index field 'buffs' (a nil value) [ShadowedUnitFrames/modules/auras.lua]:659: in function '?' [ShadowedUnitFrames/modules/units.lua]:36: in function 'FullUpdate' [ShadowedUnitFrames/modules/units.lua]:1480: in function 'CheckPlayerZone' [ShadowedUnitFrames/modules/units.lua]:1531: in function <ShadowedUnitFrames/modules/units.lua:1522>

3x ...aceShadowedUnitFrames/ShadowedUnitFrames.lua:698: attempt to index local 'frame' (a nil value) [ShadowedUnitFrames/ShadowedUnitFrames.lua]:698: in function <...aceShadowedUnitFrames/ShadowedUnitFrames.lua:695> [ShadowedUnitFrames/ShadowedUnitFrames.lua]:808: in function 'HideBlizzardFrames' [ShadowedUnitFrames/ShadowedUnitFrames.lua]:100: in function 'OnInitialize' [ShadowedUnitFrames/ShadowedUnitFrames.lua]:968: in function <...aceShadowedUnitFrames/ShadowedUnitFrames.lua:966>

@HydraxSkarrag

Copy link
Copy Markdown
Author

Pushed another round of fixes for 3 more nil-value errors that have been reported:

  1. modules/layout.lua:381 (SetupBars) - widget:GetStatusBarTexture():SetHorizTile(false) crashed when a status bar widget had no texture set yet (e.g. when the configured statusbar texture path was empty). Now guards with a nil check before calling SetHorizTile.

  2. modules/auras.lua:659 - frame.auras.buffs (or .debuffs) could be nil when Auras:Update ran before OnLayoutApplied had created the aura group, causing attempt to index field 'buffs' (a nil value). Added a nil check alongside the existing config.buffs.enabled/config.debuffs.enabled checks.

  3. ShadowedUnitFrames.lua:698 (basicHideBlizzardFrames, called from HideBlizzardFrames for RuneFrame, WarlockPowerFrame, MonkHarmonyBarFrame, PaladinPowerBarFrame, MageArcaneChargesFrame, EssencePlayerFrame) - some of those class-resource frames don't exist in this MoP 5.5.4 build, so select(i, ...) returned nil and frame:UnregisterAllEvents() crashed. Added the same if not frame then break end guard that hideBlizzardFrames already had.

Updated ZIP for testers without git: https://github.com/HydraxSkarrag/ShadowedUnitFrames/archive/refs/heads/fix/mop554-compat.zip

@jbkellen

Copy link
Copy Markdown

1631x ...ceShadowedUnitFrames/modules/monkstagger.lua:44: attempt to index global 'STAGGER_STATES' (a nil value)
[ShadowedUnitFrames/modules/monkstagger.lua]:44: in function 'Update'
[ShadowedUnitFrames/modules/monkstagger.lua]:34: in function '?'
[ShadowedUnitFrames/modules/units.lua]:36: in function 'FullUpdate'
[ShadowedUnitFrames/modules/units.lua]:376: in function 'CheckUnitStatus'
[ShadowedUnitFrames/modules/units.lua]:615: in function <ShadowedUnitFrames/modules/units.lua:441>
[C]: in function 'SetAttribute'
[ShadowedUnitFrames/modules/units.lua]:965: in function 'LoadUnit'
[ShadowedUnitFrames/modules/units.lua]:1338: in function 'InitializeFrame'
[ShadowedUnitFrames/ShadowedUnitFrames.lua]:298: in function 'LoadUnits'
[ShadowedUnitFrames/ShadowedUnitFrames.lua]:102: in function 'OnInitialize'
[ShadowedUnitFrames/ShadowedUnitFrames.lua]:968: in function <...aceShadowedUnitFrames/ShadowedUnitFrames.lua:966>

Locals:
self=

{
moduleClass="MONK"
moduleHasBar=true
moduleKey="staggerBar"
moduleSpec=

moduleName="Stagger bar"
}
frame=SUFUnitplayer units.lua:696{
vehicleUnit="vehicle"
castBar=Frame cast.lua:68
powerBar=StatusBar units.lua:1425
emptyBar=StatusBar units.lua:1425
unitType="player"
staggerBar=StatusBar units.lua:1425
indicators=Frame indicators.lua:326
portraitTexture=Texture portrait.lua:40
unit="player"
fontStrings=

TopEdge=Texture NineSlice.lua:52
unitOwner="player"
fullUpdates=

incHeal=StatusBar units.lua:1425
LeftEdge=Texture NineSlice.lua:52
portrait=Texture portrait.lua:40
registeredEvents=

TopLeftCorner=Texture NineSlice.lua:52
topFrameLevel=5
visibility=

isDead=false
unitRealType="player"
unitGUID="Player-4728-05BFC5C3"
Center=Texture NineSlice.lua:52
RightEdge=Texture NineSlice.lua:52
highFrame=Frame units.lua:718
backdropInfo=

BottomEdge=Texture NineSlice.lua:52
incAbsorb=StatusBar units.lua:1425
healthBar=StatusBar units.lua:1425
BottomRightCorner=Texture NineSlice.lua:52
BottomLeftCorner=Texture NineSlice.lua:52
TopRightCorner=Texture NineSlice.lua:52
unitInitialized=true
healAbsorb=StatusBar units.lua:1425
altPowerBar=StatusBar units.lua:1425
}
stagger=0
percent=0
state=nil
(*temporary)=nil
(*temporary)=nil
(*temporary)=nil
(*temporary)=nil
(*temporary)=nil
(*temporary)=nil
(*temporary)="attempt to index global 'STAGGER_STATES' (a nil value)"

MoP 5.5.4 (68016) doesn't define the retail STAGGER_STATES table,
causing a Lua error in Stagger:Update for Brewmaster Monks. Fall back
to the older STAGGER_YELLOW_TRANSITION/STAGGER_RED_TRANSITION globals
or hardcoded defaults if neither is available.
@HydraxSkarrag

Copy link
Copy Markdown
Author

Fixed another nil-API issue reported by a tester (Brewmaster Monk):

modules/monkstagger.lua:44: attempt to index global 'STAGGER_STATES' (a nil value)

MoP 5.5.4 (68016) doesn't define the retail STAGGER_STATES table that SUF's stagger bar color logic relies on. Now falls back to the older STAGGER_YELLOW_TRANSITION/STAGGER_RED_TRANSITION globals, or hardcoded defaults (0.3/0.6) if neither exists.

Updated test ZIP: https://github.com/HydraxSkarrag/ShadowedUnitFrames/archive/refs/heads/fix/mop554-compat.zip

@jbkellen

Copy link
Copy Markdown

For Death Knights, the rune bar doesn't show any colors (red, blue, green). It's all gray.

@HydraxSkarrag

HydraxSkarrag commented Jun 11, 2026

Copy link
Copy Markdown
Author

For Death Knights, the rune bar doesn't show any colors (red, blue, green). It's all gray.

Can you run this please and post me the results?

/run print("GetRuneType:", GetRuneType, "type1:", GetRuneType and GetRuneType(1), "type2:", GetRuneType and GetRuneType(2))

@jbkellen

Copy link
Copy Markdown

For Death Knights, the rune bar doesn't show any colors (red, blue, green). It's all gray.

Can you run this please and post me the results?

/run print("GetRuneType:", GetRuneType, "type1:", GetRuneType and GetRuneType(1), "type2:", GetRuneType and GetRuneType(2))

17:14:10] GetRuneType: function: 000001E173E3E1A8 type1: 1 type2: 1

@sfhb24

sfhb24 commented Jun 13, 2026

Copy link
Copy Markdown

Shadow priests still see magic debuff boarders for dispelling on frames.

image

@HydraxSkarrag

Copy link
Copy Markdown
Author

Addressed the "rune bar is all gray for Death Knights" report.

Turns out this branch's modules/runes.lua never had per-rune-type coloring at all (it always used a single static gray powerColors.RUNES color) - that's not a 5.5.4 regression, just a feature gap compared to other forks. Confirmed GetRuneType() still works correctly in 5.5.4 (returns 1/2/3/4 for Blood/Unholy/Frost/Death as expected).

Ported the per-type coloring (Runes:UpdateType, reacting to RUNE_POWER_UPDATE/RUNE_TYPE_UPDATE) so each rune is colored by its current type (Blood/Frost/Unholy/Death), with new configurable colors under Power Colors (RUNES_BLOOD, RUNES_FROST, RUNES_UNHOLY, RUNES_DEATH). Also added the same GetStatusBarTexture() nil-guard from the earlier layout.lua fix to the rune bar's texture setup.

Updated ZIP for testers without git: https://github.com/HydraxSkarrag/ShadowedUnitFrames/archive/refs/heads/fix/mop554-compat.zip

@jbkellen

Copy link
Copy Markdown

This is a minor issue but Incoming Heals - Outside bar limit setting is not being recognized. The incoming heal bar still goes over the health bar.

image image

@sfhb24

sfhb24 commented Jun 15, 2026

Copy link
Copy Markdown

Ready check raid indicator was not working me.
image

I wasn't getting anything on my frames.

@HydraxSkarrag

Copy link
Copy Markdown
Author

Pushed two more fixes:

  1. Ready check indicator not showing on raid frames - this branch's Indicators:UpdateReadyCheck used SetAtlas(READY_CHECK_READY_TEXTURE, TextureKitConstants.IgnoreAtlasSize) (a retail change), but in this 5.5.4 build READY_CHECK_READY_TEXTURE/_NOT_READY_/_WAITING_ don't resolve to valid atlas names, so SetAtlas silently set an empty texture. Now checks via C_Texture.GetAtlasInfo whether the constant is actually a valid atlas, and falls back to SetTexture (the pre-atlas approach) if not.

  2. Incoming heal "Outside bar limit" / proactive fix - applied the same GetStatusBarTexture() nil-guard from the earlier layout.lua fix to modules/incheal.lua's OnLayoutApplied, since it had the identical unguarded bar:GetStatusBarTexture():SetHorizTile(false) pattern that could throw and abort the rest of the sizing/cap logic.

Still investigating the "Shadow priest sees Magic debuff border" report - in MoP, baseline "Dispel Magic" (spell 527) can remove Magic debuffs for any priest spec, so a Magic-type border showing for a Shadow priest may actually be correct MoP behavior (unlike Mass Dispel, which was the earlier issue). @sfhb24 could you confirm:

  • Which specific debuff was showing the red/colored border in your screenshot?
  • Does casting Dispel Magic on that target actually remove it?

/run print("IsSpellKnown(527):", IsSpellKnown(527), GetSpellInfo(527))

Updated ZIP for testers without git: https://github.com/HydraxSkarrag/ShadowedUnitFrames/archive/refs/heads/fix/mop554-compat.zip

@jbkellen

jbkellen commented Jun 17, 2026

Copy link
Copy Markdown

Pushed two more fixes:

  1. Incoming heal "Outside bar limit" / proactive fix - applied the same GetStatusBarTexture() nil-guard from the earlier layout.lua fix to modules/incheal.lua's OnLayoutApplied, since it had the identical unguarded bar:GetStatusBarTexture():SetHorizTile(false) pattern that could throw and abort the rest of the sizing/cap logic.

Same issue with Absorb overlay (e.g. DK anti-magic shell)

image

@HydraxSkarrag

Copy link
Copy Markdown
Author

A couple of follow-ups to narrow down the two remaining open reports:


@jbkellen – absorb overlay going outside the bar limit

The absorb bars (incoming absorb / heal absorb) actually reuse the exact same layout/cap code as the incoming-heal bar, so the GetStatusBarTexture() nil-guard from the last push already applies to them too. That makes me want to confirm a few things before changing anything, so I don't fix the wrong thing:

  1. Are you on the latest ZIP? https://github.com/HydraxSkarrag/ShadowedUnitFrames/archive/refs/heads/fix/mop554-compat.zip
  2. Which frame is it on — player, target, party or raid?
  3. In that frame's options under Incoming absorbs (or Heal absorbs), what is the "Outside bar limit" slider set to? (100% = should not go outside; the default is 100%.)
  4. Do you get any Lua error when the absorb appears, or does the bar just visually overflow with no error?

If it overflows by roughly ~30% that points at a config/default value rather than the texture crash, so #3 is the key one.


@sfhb24 – Magic debuff border on Shadow Priest

Friendly bump on this one 🙂 — when you get a chance, could you run this and post the result? It tells us whether baseline Dispel Magic (527) is the reason the Magic border shows for Shadow:

/run print("IsSpellKnown(527):", IsSpellKnown(527), GetSpellInfo(527))

And: does casting Dispel Magic on that target actually remove the debuff? If it does, the Magic border may actually be correct MoP behaviour (unlike the earlier Mass Dispel case), which is why I don't want to change the curable-spell list until we're sure.

@sfhb24

sfhb24 commented Jun 19, 2026

Copy link
Copy Markdown
image

You cannot cast Dispel magic on friendly targets. It is enemy only.

The friendly dispel is a different spell, Purify, which shadow does not have access to.

All priests:
image

Only holy/disc:
image

@HydraxSkarrag

Copy link
Copy Markdown
Author

Thanks for digging into this @sfhb24 — and you're right about Purify: spell 527 (Purify) is the Holy/Disc friendly dispel, and Shadow doesn't have it (IsSpellKnown(527) returns false on Shadow, confirmed).

But that's not where the Magic border comes from. The highlight is driven by Mass Dispel (32375), which in MoP is a baseline ability for all priest specs — including Shadow. We confirmed it on a level-85 Shadow priest: IsSpellKnown(32375) returns true, and the spell is in the spellbook. Mass Dispel removes a harmful Magic effect from friendly targets, so a Shadow priest genuinely can remove that Magic debuff — just via Mass Dispel rather than Purify.

So the Magic border is actually correct MoP behaviour, unlike on retail where Mass Dispel isn't baseline for Shadow (which is why you're used to not seeing it). I'd rather not strip it out, since it does reflect a debuff you can act on.

That said — if the feeling is that Mass Dispel is too clunky (cast time, cooldown, AoE) to count as a "real" dispel for the highlight, we could drop it from the priest cure list so Shadow stops showing Magic borders (Holy/Disc are unaffected, they keep Purify). Let me know which you'd prefer.

@sfhb24

sfhb24 commented Jun 19, 2026

Copy link
Copy Markdown

It should not be shown for shadow priests. I'm not used to retail (I don't play spriest in retail) - this is how SUF functioned before 5.5.4

Its typically wrong in raids:

image

E.g. this is Sha of Pride's Mark of Arrogance (https://www.wowhead.com/mop-classic/spell=144351/mark-of-arrogance), showing me I can dispel it. Mass dispel does not work on this. At least in mop, several debuffs are coded like this to prevent spriest cheesing healer mechanics.

Spriests generally will use a custom WA if they want to track something to dispel.

Mass Dispel (32375) is baseline for all priest specs in MoP, so
IsSpellKnown(32375) is true even on Shadow, which made the dispel
highlight flag every Magic debuff as curable. In practice most raid
debuffs (e.g. Sha of Pride's Mark of Arrogance) are immune to Mass
Dispel by design, so this was a false positive. Single-target Magic
dispel is Purify (527), which only Holy/Disc have. Removing 32375 from
the priest cure list restores the pre-5.5.4 behaviour; Holy/Disc keep
their Magic highlight via Purify.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@HydraxSkarrag

Copy link
Copy Markdown
Author

Good call — that's a solid technical reason, not just a preference, so I've made the change.

Fix: Shadow priests no longer get the Magic dispel highlight. Removed Mass Dispel (32375) from the priest cure list. The reasoning matches yours: Mass Dispel is baseline for all priest specs in MoP (so IsSpellKnown(32375) is true even on Shadow), but most raid debuffs — like Mark of Arrogance — are flagged immune to it by design, so the highlight was a false positive telling Shadow it could dispel things it can't. This restores the pre-5.5.4 behaviour.

Holy/Disc are unaffected — they keep the Magic highlight via Purify (527), which is the real single-target dispel and which Shadow doesn't have.

Updated ZIP for testers without git: https://github.com/HydraxSkarrag/ShadowedUnitFrames/archive/refs/heads/fix/mop554-compat.zip

@jbkellen

Copy link
Copy Markdown

A couple of follow-ups to narrow down the two remaining open reports:

@jbkellen – absorb overlay going outside the bar limit

The absorb bars (incoming absorb / heal absorb) actually reuse the exact same layout/cap code as the incoming-heal bar, so the GetStatusBarTexture() nil-guard from the last push already applies to them too. That makes me want to confirm a few things before changing anything, so I don't fix the wrong thing:

  1. Are you on the latest ZIP? https://github.com/HydraxSkarrag/ShadowedUnitFrames/archive/refs/heads/fix/mop554-compat.zip
  2. Which frame is it on — player, target, party or raid?
  3. In that frame's options under Incoming absorbs (or Heal absorbs), what is the "Outside bar limit" slider set to? (100% = should not go outside; the default is 100%.)
  4. Do you get any Lua error when the absorb appears, or does the bar just visually overflow with no error?

If it overflows by roughly ~30% that points at a config/default value rather than the texture crash, so #3 is the key one.

  1. Yes I am on the latest one. I tried both zip files you linked on this post and the one with Fix: Shadow priests no longer get the Magic dispel highlight.
  2. Player Frame
  3. I don't see any "Incoming absobs" for the player frame bar. Only "Incoming heals" and it's set as 100% outside bar limit.
  4. There are no lua errors. The overflow just shows.

@HydraxSkarrag

Copy link
Copy Markdown
Author

Thanks, that's really helpful — especially #3 and #4. The anti-magic shell is a damage absorb, which is drawn by the Incoming absorbs bar (a separate bar from Incoming heals), so the 100% you set on Incoming heals doesn't apply to it. That it overflows with no Lua error points at a config value rather than the texture crash.

Could you run this one line and paste the output? It reads the actual limit values your profile is using:

/run local u=ShadowUF.db.profile.units.player print("incHeal.cap:",u.incHeal.cap," incAbsorb.cap:",u.incAbsorb and u.incAbsorb.cap," incAbsorb.enabled:",u.incAbsorb and u.incAbsorb.enabled," healAbsorb.cap:",u.healAbsorb and u.healAbsorb.cap)

If incAbsorb.cap comes back as nil, that's the bug — it falls back to 130% internally, which is exactly the ~30% overflow you're seeing. I'll fix the fallback so it respects the 100% default.

Also: under the player frame options there should be an "Incoming absorbs" section just below "Incoming heals" — if you genuinely don't see it, let me know, that's a second thing to look at.

@jbkellen

Copy link
Copy Markdown

/run local u=ShadowUF.db.profile.units.player print("incHeal.cap:",u.incHeal.cap," incAbsorb.cap:",u.incAbsorb and u.incAbsorb.cap," incAbsorb.enabled:",u.incAbsorb and u.incAbsorb.enabled," healAbsorb.cap:",u.healAbsorb and u.healAbsorb.cap)

image image

@HydraxSkarrag

Copy link
Copy Markdown
Author

Closing this in favour of a corrected PR — apologies for the mix-up.

This PR was opened against master (the retail line, 11.x), but the real target is MoP Classic 5.5.4, which belongs on the upstream classic branch. Running retail code on a Classic client is exactly what produced most of the crashes we chased here (monk stagger, GetSpecialization, the absorb modules…) — none of which even exist on classic.

Full transparency on how this happened: the fix was done with AI assistance (Claude Code), and the mix-up came from it effectively working with a kind of split brain — patching my local Classic install on one side, while developing this PR against the retail master branch on the other, without ever reconciling that those are two different code lines. Once we lined the two up, it was obvious the work belonged on classic all along — where it's also far smaller (a few nil-guards + a DebuffTypeColor rebuild).

The new build is the version I'm running myself in-game on live 5.5.4 without any problems — raiding on a Warlock, and smooth on a Feral Druid and Elemental Shaman too.

New PR: #70

Huge thanks for all the testing @jbkellen @sfhb24 @almx @100mll 🙏 — could you re-test the classic build instead? You only need to replace the ShadowedUnitFrames folder (your options addon is unchanged). ZIP:
https://github.com/HydraxSkarrag/ShadowedUnitFrames/archive/refs/heads/fix/mop554-classic.zip

@jbkellen

jbkellen commented Jun 22, 2026

Copy link
Copy Markdown

Huge thanks for all the testing @jbkellen @sfhb24 @almx @100mll 🙏 — could you re-test the classic build instead? You only need to replace the ShadowedUnitFrames folder (your options addon is unchanged). ZIP: https://github.com/HydraxSkarrag/ShadowedUnitFrames/archive/refs/heads/fix/mop554-classic.zip

Getting a bunch of lua errors due to the libs folder missing. I copied libs folder from prior zip and will continue to test. Thanks.

@HydraxSkarrag

Copy link
Copy Markdown
Author

@jbkellen good catch, thanks — and sorry for the hassle. The raw GitHub source ZIP doesn't include the libs/ folder (the libraries are pulled in only at packaging time), which is exactly why you got the wave of Lua errors.

I've put up a pre-packaged build that bundles libs/ so you don't have to copy them manually:

➡️ https://github.com/HydraxSkarrag/ShadowedUnitFrames/releases/download/mop554-classic-test/ShadowedUnitFrames-mop554-classic.zip

Just extract into Interface/AddOns/ (it has both ShadowedUnitFrames/ and ShadowedUF_Options/) and overwrite. It's the same code as #70, where I've also linked it. Thanks again for testing!

@jbkellen

Copy link
Copy Markdown

@jbkellen good catch, thanks — and sorry for the hassle. The raw GitHub source ZIP doesn't include the libs/ folder (the libraries are pulled in only at packaging time), which is exactly why you got the wave of Lua errors.

I've put up a pre-packaged build that bundles libs/ so you don't have to copy them manually:

➡️ https://github.com/HydraxSkarrag/ShadowedUnitFrames/releases/download/mop554-classic-test/ShadowedUnitFrames-mop554-classic.zip

Just extract into Interface/AddOns/ (it has both ShadowedUnitFrames/ and ShadowedUF_Options/) and overwrite. It's the same code as #70, where I've also linked it. Thanks again for testing!

I don't know if this is a feature of the retail code or an issue with the classic code, but for the version I was testing before #70 whenever I get onto a vehicle, the Player Frame changes to the Vehicle frame:

image

With the latest classic version, the player frame doesn't change, and the cast bar of the vehicle no longer shows.

image

@HydraxSkarrag

Copy link
Copy Markdown
Author

Thanks @jbkellen! Moving this one to #70 to keep it on the correct (classic) branch — I've replied there in detail: #70

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.

5 participants