This code, as written, never could have worked. In the global context (i.e. where timer and cancelTimer are defined) there really is no context. This means cancelTimer can’t see timer. You have to pass timer as an argument for it to see it. This has been the case since OH 1.6.
Beyond that, except for the log statements that entire lambda is unnecessary. You can do the same thing with two lines of code:
timer?.cancel
timer = null
Finally, if you starting to head down the path of wanting to create lambdas to do stuff like this I cannot encourage you strongly enough to abandon Rules DSL and move to Scripted Automation. Right now Python is the best documented and has the most users and examples.
Rules DSL global lambdas are not thread safe, they suppress errors, everything needs to be passed to it as an argument but you can only have seven arguments, and they can only be accessed from the one .rules file. When I see lambdas used like this, it’s a code smell. You are heading towards hard to diagnose and random errors and brittle code that is hard to maintain.