As RoCk said, $chan will be $null when the timer fires, so you'd have to pass it in the alias, except not in the way you and RussellB showed. Once more (this has been pointed out to both of you more times than it should),
you should not pass unknown content to /timer, including $chan. Channel names can have special characters like % and $, and a string of the form
#$something evaluates to $something, if the latter is a built-in identifier. If $something is a custom identifier, it won't be called by #$something (possibly a (weak) security precaution), but it
will be called by
#$($something) (still a valid channel name). Now imagine the situation where $something is a custom identifier that does something potentially dangerous (eg delete files)...
You should both really burn this issue into your minds; posting insecure code over and over has to stop. The fact that #$something works like that has been mentioned a few times in these forums. You know by now what to do to write safe code (eg use the
$safe alias I posted the last time this issue came up).
There are also a couple of less serious issues.
First, $lines(file.txt) should be stored in a variable, then that variable should be used inside the loop. This is important in this case, because you don't know for sure how many times it will loop, so having mirc calculate the number of lines (a slow operation on moderately large files) each time will certainly cause problems.
Another problem is the /inc -u method, which can be horribly inaccurate. Each time /inc -u is called,
it restarts the 2-hour timer. Consider this example: line 4 happens to be picked once every, say, 13 times (starting from the first call). This means that every 13*300 (the latter being the /timer interval), ie 6900 seconds, the -u timer for %Random.4 would be reset just before it expired (more precisely, 5 minutes before). This way %Random.4 would reach the value 10 in 6900*10 secs, ie in about 19 hours, and the script would skip it (although it obviously shouldn't). This would exacerbate the not-enough-lines problem you described, by unnecessarily skipping line 4. A more accurate way would be to /set -u7200 %Random.<line> 1 if the variable doesn't exist, otherwise /inc it (without -u).