Agent skill
inheritance-debugging
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/development/inheritance-debugging
SKILL.md
Skill: inheritance-debugging
Scope
Debug constructor inheritance issues where subclass properties are accessed before initialization.
Does:
- Diagnose "undefined is not iterable" and NaN calculation errors
- Fix super() initialization order problems
- Add fallback defaults in render methods
- Verify fixes with incremental testing
Does Not:
- Cover general JavaScript debugging
- Handle non-inheritance related bugs
Context
In jsgui3 controls, a common pattern is:
- Base class constructor calls
compose()orrender() - Subclass constructor calls
super(spec)then sets its own properties - Problem: Base class render runs BEFORE subclass properties exist
This manifests as:
undefined is not iterablewhen destructuringthis._propertyNaNcalculations using undefined numeric properties- Missing SVG attributes (x, width, height)
- Silent failures with empty renders
Procedure
1. Identify the Pattern
Look for this constructor structure:
class Child extends Parent {
constructor(spec) {
super(spec); // ← Parent calls render() here
this._my_property = spec.value || 'default'; // ← Too late!
}
}
2. Run Isolated Tests
Create a debug script to test with abstract: true:
const control = new MyControl({
context,
abstract: true, // Skips compose/render
...options
});
console.log('Properties:', control._my_property);
If it works with abstract: true but fails without, this confirms the timing issue.
3. Add Fallback Defaults in Methods
In every method that uses subclass properties, add defaults:
// Before (breaks during super())
render() {
const [min, max] = this._range; // undefined error
const gap = this._gap; // NaN
}
// After (safe)
render() {
const range = this._range || [-10, 10]; // Fallback
const [min, max] = range;
const gap = this._gap !== undefined ? this._gap : 0.1;
}
4. Add Re-render After Properties Set
In the subclass constructor, re-render after setting properties:
constructor(spec) {
super(spec); // Renders with defaults
this._my_property = spec.value || 'default';
// Re-render now that properties are set
if (!spec.abstract && !spec.el && this._svg) {
this.render_chart();
}
}
5. Verify with Browser Subagent
Use browser testing to visually confirm the fix:
1. Start demo server
2. Navigate to demo page
3. Inspect rendered elements for correct attributes
4. Check console for errors
5. Screenshot for documentation
6. Run Unit Tests
Ensure all tests pass after the fix:
npx mocha test/controls/<control>.test.js --reporter min
Real Example: Bar_Chart Fix
Problem: Bar rects had y and height but missing x and width.
Root Cause: super(spec) called compose_chart() → render_chart() → render_bars(), which used this._bar_gap before it was set.
Fix: Added fallback in render_bars():
const bar_gap = this._bar_gap !== undefined ? this._bar_gap : 0.1;
const group_gap = this._group_gap !== undefined ? this._group_gap : 0.2;
Result: 35 chart tests passing, bars render correctly.
Validation Checklist
- Identified properties accessed before initialization
- Added fallback defaults to all affected methods
- Added re-render call after subclass properties set
- Debug script with
abstract: trueworks - Debug script without
abstract: trueworks - Unit tests pass
- Browser visual verification passed
References
- Chart_Base.js - Example of base class
- Bar_Chart.js - Fixed subclass example
- Function_Graph.js - Another fixed example
Didn't find tool you were looking for?