@@ -528,16 +528,12 @@ component {
528528 * Supports comma-delimited variable names to constrain multiple variables at once.
529529 */
530530 public struct function $applyConstraintToLastRoute (required string variableName , required string pattern ) {
531- // Cache the application key and routes array reference to avoid repeated
532- // dynamic key resolution via $appKey(). On Adobe CF, chained expressions
533- // like application[$appKey()].routes[i] can cause unexpected runtime errors
534- // when accessing array elements from application-scoped structs.
535- local .appKey = " wheels" ;
536- if (StructKeyExists (application , " $wheels" )) {
537- local .appKey = " $wheels" ;
538- }
539- local .appRoutes = application [local .appKey ].routes ;
540- local .routeCount = ArrayLen (local .appRoutes );
531+ // Work exclusively with variables.routes (the Mapper's internal copy) to
532+ // avoid Adobe CF runtime errors. Adobe CF returns application-scoped array
533+ // elements by value, and chained expressions like
534+ // application[key].routes[i].member cause "dereference scalar as struct"
535+ // errors. After modifying routes here, we sync back to application scope.
536+ local .routeCount = ArrayLen (variables .routes );
541537 if (local .routeCount == 0 ) {
542538 Throw (
543539 type = " Wheels.NoRouteToConstrain" ,
@@ -548,7 +544,7 @@ component {
548544 // Apply constraint to the last route (and its optional-segment variants).
549545 // When optional segments are used, $match adds multiple routes. We apply the
550546 // constraint to all routes that share the same name as the last one.
551- local .lastRoute = local . appRoutes [local .routeCount ];
547+ local .lastRoute = variables . routes [local .routeCount ];
552548 local .lastRouteName = StructKeyExists (local .lastRoute , " name" ) ? local .lastRoute .name : " " ;
553549
554550 local .variables = ListToArray (arguments .variableName );
@@ -557,7 +553,7 @@ component {
557553
558554 // Walk backward through routes to find all variants of the same named route.
559555 for (local .i = local .routeCount ; local .i >= 1 ; local .i -- ) {
560- local .route = local . appRoutes [local .i ];
556+ local .route = variables . routes [local .i ];
561557 local .routeName = StructKeyExists (local .route , " name" ) ? local .route .name : " " ;
562558
563559 // Stop if we've gone past the related routes.
@@ -575,46 +571,26 @@ component {
575571 // Recompile the regex with the new constraint.
576572 local .route .regex = $patternToRegex (local .route .pattern , local .route .constraints );
577573
578- // Explicit write-back: on Adobe CF, array elements from the
579- // application scope are returned by value. Write the modified
580- // struct back directly to the application-scoped array to
581- // ensure changes persist (not via a local reference which may
582- // be a copy on some engines).
583- application [local .appKey ].routes [local .i ] = local .route ;
574+ // Write back to the internal array (Adobe CF returns array
575+ // elements by value, so the local copy must be written back).
576+ variables .routes [local .i ] = local .route ;
584577 }
585578
586579 // If no name, only update the very last route.
587580 if (! Len (local .lastRouteName )) {
588581 break ;
589582 }
590583 }
584+ }
591585
592- // Also update the internal routes array.
593- local .internalCount = ArrayLen (variables .routes );
594- for (local .i = local .internalCount ; local .i >= 1 ; local .i -- ) {
595- local .route = variables .routes [local .i ];
596- local .routeName = StructKeyExists (local .route , " name" ) ? local .route .name : " " ;
597-
598- if (Len (local .lastRouteName ) && local .routeName ! = local .lastRouteName && local .i < local .internalCount ) {
599- break ;
600- }
601-
602- if (Find (" [#local .varName #]" , local .route .pattern )) {
603- if (! StructKeyExists (local .route , " constraints" )) {
604- local .route .constraints = {};
605- }
606- local .route .constraints [local .varName ] = arguments .pattern ;
607- local .route .regex = $patternToRegex (local .route .pattern , local .route .constraints );
608-
609- // Explicit write-back for Adobe CF safety (see comment above).
610- variables .routes [local .i ] = local .route ;
611- }
612-
613- if (! Len (local .lastRouteName )) {
614- break ;
615- }
616- }
586+ // Sync modified routes back to application scope. We replace the entire
587+ // array to avoid per-element access on application-scoped arrays, which
588+ // triggers Adobe CF's "dereference scalar as struct" errors.
589+ local .appKey = " wheels" ;
590+ if (StructKeyExists (application , " $wheels" )) {
591+ local .appKey = " $wheels" ;
617592 }
593+ application [local .appKey ].routes = variables .routes ;
618594
619595 return this ;
620596 }
0 commit comments