Fix: AbstractController.threadLocal must be static, so it’s shared between all controllers