There are two syntaxes for getting repeating section attributes. The form you have used, repeating_pc4_pcproj4 is the per-row syntax. For this to work, it must be triggered within a row of a repeating section, and roll20 automatically inserts a row id into the attribute name, so it becomes something like repeating_pc4_-ghty6453bcg_pcproj4 Such events can only work for a single row at a time, and are incompatible with the sheet:opened event. If you want something to affect every row of a repeating section (as with sheet:opened), your worker has to build the complete address for every row in the section, and that's where getSectionIDs comes in. So a worker to do this would look something like: on ( 'sheet:opened' , function (){ getSectionIDs ( 'repeating_pc4' , function ( id_array ) { // the next line builds an array of attribute names, for the entire section. Don't worry about how it works. const rows = id_array . reduce (( all_rows , id ) => [... all_rows , `repeating_pc4_ ${ id } _pcproj4` ], []); getAttrs ( rows , function ( values ) { // the values object contains all the row attribute names and their values. //create an empty object variable to hold the values const output = {}; // loop throw the rows array rows . forEach ( function ( row ) { // with each row, grab its value const score = + v [ row ] || 0 ; //check if its below zero annd update it if so if ( score < 0 ) { // if it's below zero, save the updated value to output output [ row ] = 0 ; } //if output has values, save to the sheet. if ( Object . keys ( output ). length ) { setAttrs ( output ); } }); }); }); }); However... The function you are doing here - check if a value is below zero and set to 0 if so, should not be done like this. It should be done in a response to the attribute change event. If you are using this value anywhere, you'd use it in that code. But if not, you can use your per-use syntax, like so: on ( 'change:repeating_pc4_pcproj4' , function () { getAttrs ([ 'repeating_pc4_pcproj4' ], function ( values ) { const score = + values . repeating_pc4_pcproj4 || 0 ; if ( score < 0 ) { // if it's below zero, save the updated value to output setAttrs ({ repeating_pc4_pcproj4 : 0 }); } }); }); This checks the attribute value every time it is changed, and resets its value to 0 if below that. The setAttrs function only runs when the attribute is zero, and the whole function only runs when a specific row attribute is changed. This way there is no lag time: if you tie the check to sheet:opened means that characters may have attributes that show a wrong value, until the sheet is closed and opened again. This avoids that.