Thank you all for the responses, I went back and reworked it as a sheet worker>  Sheet worker:  // Common parser function function parseDamageString(damageString, prefix) {   const updates = {};    const match = damageString.match(/^(\d+)[dD](\d+)([+\-]\d+)?$/);    if (match) {     const numDice = parseInt(match[1], 10) || 0;     const diceSize = parseInt(match[2], 10) || 0;     const bonus = parseInt(match[3] || "0", 10) || 0;      updates[`${prefix}_damage_numdice`] = numDice;     updates[`${prefix}_damage_dicesize`] = diceSize;     updates[`${prefix}_damage_bonus`] = bonus;   } else {     updates[`${prefix}_damage_numdice`] = 0;     updates[`${prefix}_damage_dicesize`] = 0;     updates[`${prefix}_damage_bonus`] = 0;   }    return updates; }  // Auto-calculate damage components for fixed weapon (weapon1_mdr) on("sheet:opened add:weapon1_mdr_damage change:weapon1_mdr_damage", function() {   getAttrs(["weapon1_mdr_damage"], function(values) {     const damageString = values.weapon1_mdr_damage || "";     const updates = parseDamageString(damageString, "weapon1_mdr");     setAttrs(updates);   }); });  // Auto-calculate damage components for repeating weapons (repeating_weaponsmdr) - change only on("add:repeating_weaponsmdr change:repeating_weaponsmdr:weapondamage_mdr", function(eventInfo) {   const repeatingId = eventInfo.sourceAttribute.match(/repeating_weaponsmdr_([^_]+)_/)[1];    getAttrs([`repeating_weaponsmdr_${repeatingId}_weapondamage_mdr`], function(values) {     const damageString = values[`repeating_weaponsmdr_${repeatingId}_weapondamage_mdr`] || "";     const updates = parseDamageString(damageString, `repeating_weaponsmdr_${repeatingId}`);     setAttrs(updates);   }); });  // On sheet:opened, manually get all repeating rows on("sheet:opened", function() {   getSectionIDs("repeating_weaponsmdr", function(ids) {     if (ids.length === 0) return;      const fields = ids.map(id => `repeating_weaponsmdr_${id}_weapondamage_mdr`);     getAttrs(fields, function(values) {       const updates = {};        ids.forEach(id => {         const damageString = values[`repeating_weaponsmdr_${id}_weapondamage_mdr`] || "";         Object.assign(updates, parseDamageString(damageString, `repeating_weaponsmdr_${id}`));       });        if (Object.keys(updates).length > 0) {         setAttrs(updates);       }     });   }); });  Hidden inputs for static weapon:  <input type="hidden" name="attr_weapon1_mdr_damage_numdice" value="0" /> <input type="hidden" name="attr_weapon1_mdr_damage_dicesize" value="0" /> <input type="hidden" name="attr_weapon1_mdr_damage_bonus" value="0" /> <input type="hidden" name="attr_weapon1_mdr_strain" value="0" />   Static Weapon Roll:   <button class='new-roll' type='roll' value='&{template:coc-attack-1} {{name=@{weapon1_mdr_name}}} {{modifier=@{dice_modifier_checkbox}}} {{success=[[@{weapon1_skill_mdr}+@{dice_modifier_checkbox}]]}} {{hard=[[floor((@{weapon1_skill_mdr} + @{dice_modifier_checkbox})/2)]]}} {{extreme=[[floor((@{weapon1_skill_mdr} + @{dice_modifier_checkbox})/5)]]}} {{malf=@{weapon1_mdr_malf}}} {{roll1=[[1d100]]}} {{damage=[[@{weapon1_mdr_damage}@{weapon1_mdr_db}]]}} {{extremedamage=[[(@{weapon1_mdr_damage_numdice}*@{weapon1_mdr_damage_dicesize})+@{weapon1_mdr_damage_bonus}]]}} {{strain=[[ @{weapon1_mdr_strain} + 0 ]]}}' name='roll_weapon1_mdr_attack' />   Hidden Inputs for repeating weapon:    <input type="hidden" name="attr_damage_numdice" value="0" /> <input type="hidden" name="attr_damage_dicesize" value="0" /> <input type="hidden" name="attr_damage_bonus" value="0" /> <input type="hidden" name="attr_weaponstrain_mdr" value="0" />  Repeating Weapon Roll:    <button class='new-roll' type='roll' value='&{template:coc-attack-1} {{name=@{weaponname_mdr}}} {{modifier=@{dice_modifier_checkbox}}} {{success=[[@{weaponskill_mdr}+@{dice_modifier_checkbox}]]}} {{hard=[[floor((@{weaponskill_mdr}+@{dice_modifier_checkbox})/2)]]}} {{extreme=[[floor((@{weaponskill_mdr}+@{dice_modifier_checkbox})/5)]]}} {{malf=@{weaponmalf_mdr}}} {{roll1=[[1d100]]}} {{damage=[[@{weapondamage_mdr}@{weapondb_mdr}]]}} {{extremedamage=[[(@{damage_numdice}*@{damage_dicesize})+@{damage_bonus}]]}} {{strain=[[ @{weaponstrain_mdr} + 0 ]]}}' name='roll_weaponskill_mdr_check' />   Roll Template:    <!-- &{template:coc-attack-1} --------------------------------------------------------------------------------------------------------- --> <rolltemplate class="sheet-rolltemplate-coc-attack-1">     <table>         <caption>{{name}} | {{modifier}}</caption>         <tr><td class="template_label" data-i18n="value">Value:</td><td class="template_value">{{success}}/{{hard}}/{{extreme}}</td></tr>         {{#malf}}             <tr><td class="template_label" data-i18n="malf">Malf:</td><td class="template_value">{{malf}}</td></tr>         {{/malf}}         <tr><td class="template_label" data-i18n="rolled">Rolled:</td><td class="template_value">{{roll1}}</td></tr>         <tr style="background:#BEBEBE;">             <td class="template_label" data-i18n="result">Result:</td>             <!-- 01 is always Critical -->             {{#rollTotal() roll1 1}}                 <td style="background:Lime;" class="template_value"><b data-i18n="critical">Critical</b></td>             {{/rollTotal() roll1 1}}             <!-- Is Success -->             {{#rollBetween() roll1 2 success}}                 <!-- Is Standard -->                 {{#rollGreater() roll1 hard}}                     <td style="background:DarkGreen;" class="template_value" data-i18n="success">Success</td>                 {{/rollGreater() roll1 hard}}                 <!-- Is Hard or Extreme -->                 {{#rollBetween() roll1 2 hard}}                     <!-- Is Hard -->                     {{#rollGreater() roll1 extreme}}                         <td style="background:Green;" class="template_value" data-i18n="hard">Hard</td>                     {{/rollGreater() roll1 extreme}}                     <!-- Is Extreme -->                     {{#rollBetween() roll1 2 extreme}}                         <td style="background:LightGreen;" class="template_value"><b data-i18n="extreme">Extreme</b></td>                     {{/rollBetween() roll1 2 extreme}}                 {{/rollBetween() roll1 2 hard}}             {{/rollBetween() roll1 2 success}}             <!-- Is Not Success -->             {{#rollGreater() roll1 success}}                 <!-- Is skill >= 50 -->                 {{#rollGreater() success 49}}                     <!-- Is Fumble -->                     {{#rollTotal() roll1 100}}                         <td style="background:Red;" class="template_value"><b data-i18n="fumble">Fumble</b></td>                     {{/rollTotal() roll1 100}}                     <!-- Is Fail -->                     {{#rollLess() roll1 100}}                         <td style="background:Crimson;" class="template_value" data-i18n="fail">Fail</td>                     {{/rollLess() roll1 100}}                 {{/rollGreater() success 49}}                 <!-- Is skill < 50 -->                 {{#rollLess() success 50}}                     <!-- Is Fumble -->                     {{#rollGreater() roll1 95}}                         <td style="background:Red;" class="template_value"><b data-i18n="fumble">Fumble</b></td>                     {{/rollGreater() roll1 95}}                     <!-- Is Fail -->                     {{#rollLess() roll1 96}}                         <td style="background:Crimson;" class="template_value" data-i18n="fail">Fail</td>                     {{/rollLess() roll1 96}}                 {{/rollLess() success 50}}             {{/rollGreater() roll1 success}}         </tr>         <tr> 			<td class="template_label" data-i18n="dam">Dam:</td><td class="template_value">{{damage}}</td> 		</tr>         <!-- Only show Extreme Damage on Critical or Extreme -->         {{#rollTotal() roll1 1}}             <tr>                 <td class="template_label" data-i18n="extremedamage">Extreme Dam:</td><td class="template_value">{{extremedamage}}</td>             </tr>         {{/rollTotal() roll1 1}}         {{#rollBetween() roll1 2 extreme}}             <tr>                 <td class="template_label" data-i18n="extreme-damage">Extreme Dam:</td><td class="template_value">{{extremedamage}}</td>             </tr>         {{/rollBetween() roll1 2 extreme}} 		{{#^rollTotal() strain 0}}             <tr> 			    <td class="template_label" data-i18n="strain">Strain:</td><td class="template_value">{{strain}}</td>             </tr> 		{{/^rollTotal() strain 0}}      </table> </rolltemplate>