How about just doing it similar to the way mksh resolves arithmetic variable loops? As each variable is visited, add it to a list (or hash set) and check whether that node was already visited. That should work without having to consider scope issues.
$ mksh -c 'a=b b=c c=d d=1; echo $((a))' 1 $ mksh -c 'a=b b=c c=d d=a; echo $((a))' mksh: a: expression recurses on parameter 'a' This nicely says which variable was to blame. I've noticed bash devel right now can give messages about "invalid identifiers" which are technically valid in most contexts so it's tough to track down problems in complicated reference chains.