2025-04-08 00:03:04.031 [WARN ] [org.eclipse.jetty.server.HttpChannel] - /tado
com.google.gson.JsonIOException: Failed making field 'java.lang.Throwable#detailMessage' accessible; either increase its visibility or write a custom TypeAdapter for its declaring type.
See https://github.com/google/gson/blob/main/Troubleshooting.md#reflection-inaccessible
at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:76) ~[?:?]
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:388) ~[?:?]
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:161) ~[?:?]
at com.google.gson.Gson.getAdapter(Gson.java:628) ~[?:?]
at com.google.gson.Gson.fromJson(Gson.java:1360) ~[?:?]
at com.google.gson.Gson.fromJson(Gson.java:1262) ~[?:?]
at com.google.gson.Gson.fromJson(Gson.java:1171) ~[?:?]
at com.google.gson.Gson.fromJson(Gson.java:1107) ~[?:?]
at org.openhab.core.auth.oauth2client.internal.OAuthConnectorRFC8628.fetchAccessTokenResponse(OAuthConnectorRFC8628.java:358) ~[?:?]
at org.openhab.core.auth.oauth2client.internal.OAuthConnectorRFC8628.getDeviceCodeResponse(OAuthConnectorRFC8628.java:204) ~[?:?]
at org.openhab.core.auth.oauth2client.internal.OAuthClientServiceImpl.getDeviceCodeResponse(OAuthClientServiceImpl.java:476) ~[?:?]
at org.openhab.binding.tado.internal.handler.TadoHandlerFactory.getDeviceCodeResponse(TadoHandlerFactory.java:223) ~[?:?]
at org.openhab.binding.tado.internal.servlet.TadoAuthenticationServlet.serveUserAuthenticationPage(TadoAuthenticationServlet.java:148) ~[?:?]
at org.openhab.binding.tado.internal.servlet.TadoAuthenticationServlet.doGet(TadoAuthenticationServlet.java:81) ~[?:?]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:497) ~[bundleFile:4.0.4]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:584) ~[bundleFile:4.0.4]
at org.ops4j.pax.web.service.spi.servlet.OsgiInitializedServlet.service(OsgiInitializedServlet.java:102) ~[?:?]
at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1450) ~[?:?]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[?:?]
at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1656) ~[?:?]
at org.ops4j.pax.web.service.spi.servlet.OsgiFilterChain.doFilter(OsgiFilterChain.java:113) ~[?:?]
at org.ops4j.pax.web.service.jetty.internal.PaxWebServletHandler.doHandle(PaxWebServletHandler.java:334) ~[?:?]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[?:?]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600) ~[?:?]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[?:?]
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) ~[?:?]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) ~[?:?]
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[?:?]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440) ~[?:?]
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) ~[?:?]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505) ~[?:?]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) ~[?:?]
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) ~[?:?]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355) ~[?:?]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[?:?]
@andrea636 please turn on log:set TRACE org.openhab.core.auth
and post the result.
2025-04-08 12:09:23.530 [WARN ] [o.internal.handler.SystemInfoHandler] - No information for channel sensors#fanSpeed with device index: 0
2025-04-08 12:09:31.560 [TRACE] [lient.internal.OAuthConnectorRFC8628] - getDeviceCodeResponse() start..
2025-04-08 12:09:31.560 [TRACE] [lient.internal.OAuthConnectorRFC8628] - getDeviceCodeResponse() loaded from service: AccessTokenResponse [null]
2025-04-08 12:09:31.568 [TRACE] [lient.internal.OAuthConnectorRFC8628] - fetchDeviceCodeResponse() request: https://login.tado.com/oauth2/device_authorize?client_id=1bb50063-6b0c-4d11-bd99-387f4a91cc46&scope=offline_access
2025-04-08 12:09:31.751 [TRACE] [lient.internal.OAuthConnectorRFC8628] - fetchDeviceCodeResponse() response: {"device_code":"Akg0IvXiSRut8w2krUBwe-kMBSLi08NQF45Eoxcaa3c","expires_in":300,"interval":5,"user_code":"XWTTDJ","verification_uri":"https://login.tado.com/oauth2/device","verification_uri_complete":"https://login.tado.com/oauth2/device?user_code=XWTTDJ"}
2025-04-08 12:09:31.752 [TRACE] [lient.internal.OAuthConnectorRFC8628] - fetchDeviceCodeResponse() return: DeviceCodeResponseDTO [deviceCode=Akg0IvXiSRut8w2krUBwe-kMBSLi08NQF45Eoxcaa3c, expiresIn=300, interval=5, userCode=XWTTDJ, verificationUri=https://login.tado.com/oauth2/device, verificationUriComplete=https://login.tado.com/oauth2/device?user_code=XWTTDJ, createdOn=2025-04-08T10:09:31.751549500Z]
2025-04-08 12:09:31.752 [TRACE] [lient.internal.OAuthConnectorRFC8628] - getDeviceCodeResponse() fetched from remote: DeviceCodeResponseDTO [deviceCode=Akg0IvXiSRut8w2krUBwe-kMBSLi08NQF45Eoxcaa3c, expiresIn=300, interval=5, userCode=XWTTDJ, verificationUri=https://login.tado.com/oauth2/device, verificationUriComplete=https://login.tado.com/oauth2/device?user_code=XWTTDJ, createdOn=2025-04-08T10:09:31.751549500Z]
2025-04-08 12:09:31.752 [TRACE] [lient.internal.OAuthConnectorRFC8628] - fetchAccessTokenResponse() request: https://login.tado.com/oauth2/token?client_id=1bb50063-6b0c-4d11-bd99-387f4a91cc46&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=Akg0IvXiSRut8w2krUBwe-kMBSLi08NQF45Eoxcaa3c
2025-04-08 12:09:31.849 [TRACE] [lient.internal.OAuthConnectorRFC8628] - fetchAccessTokenResponse() response: {"error":"authorization_pending","error_description":"The authorization request is still pending"}
2025-04-08 12:09:31.851 [WARN ] [org.eclipse.jetty.server.HttpChannel] - /tado
com.google.gson.JsonIOException: Failed making field 'java.lang.Throwable#detailMessage' accessible; either increase its visibility or write a custom TypeAdapter for its declaring type.
See https://github.com/google/gson/blob/main/Troubleshooting.md#reflection-inaccessible
at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:76) ~[?:?]
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:388) ~[?:?]
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:161) ~[?:?]
at com.google.gson.Gson.getAdapter(Gson.java:628) ~[?:?]
at com.google.gson.Gson.fromJson(Gson.java:1360) ~[?:?]
at com.google.gson.Gson.fromJson(Gson.java:1262) ~[?:?]
at com.google.gson.Gson.fromJson(Gson.java:1171) ~[?:?]
at com.google.gson.Gson.fromJson(Gson.java:1107) ~[?:?]
at org.openhab.core.auth.oauth2client.internal.OAuthConnectorRFC8628.fetchAccessTokenResponse(OAuthConnectorRFC8628.java:358) ~[?:?]
at org.openhab.core.auth.oauth2client.internal.OAuthConnectorRFC8628.getDeviceCodeResponse(OAuthConnectorRFC8628.java:204) ~[?:?]
at org.openhab.core.auth.oauth2client.internal.OAuthClientServiceImpl.getDeviceCodeResponse(OAuthClientServiceImpl.java:476) ~[?:?]
at org.openhab.binding.tado.internal.handler.TadoHandlerFactory.getDeviceCodeResponse(TadoHandlerFactory.java:223) ~[?:?]
at org.openhab.binding.tado.internal.servlet.TadoAuthenticationServlet.serveUserAuthenticationPage(TadoAuthenticationServlet.java:148) ~[?:?]
at org.openhab.binding.tado.internal.servlet.TadoAuthenticationServlet.doGet(TadoAuthenticationServlet.java:81) ~[?:?]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:497) ~[bundleFile:4.0.4]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:584) ~[bundleFile:4.0.4]
at org.ops4j.pax.web.service.spi.servlet.OsgiInitializedServlet.service(OsgiInitializedServlet.java:102) ~[?:?]
at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1450) ~[?:?]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[?:?]
at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1656) ~[?:?]
at org.ops4j.pax.web.service.spi.servlet.OsgiFilterChain.doFilter(OsgiFilterChain.java:113) ~[?:?]
at org.ops4j.pax.web.service.jetty.internal.PaxWebServletHandler.doHandle(PaxWebServletHandler.java:334) ~[?:?]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[?:?]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600) ~[?:?]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[?:?]
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) ~[?:?]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) ~[?:?]
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[?:?]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440) ~[?:?]
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) ~[?:?]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505) ~[?:?]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) ~[?:?]
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) ~[?:?]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355) ~[?:?]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[?:?]
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:234) ~[?:?]
at org.ops4j.pax.web.service.jetty.internal.PrioritizedHandlerCollection.handle(PrioritizedHandlerCollection.java:96) ~[?:?]
at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:731) ~[?:?]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[?:?]
at org.eclipse.jetty.server.Server.handle(Server.java:516) ~[?:?]
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487) ~[?:?]
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732) ~[?:?]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479) ~[?:?]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) ~[?:?]
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) ~[?:?]
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) ~[?:?]
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) ~[?:?]
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) ~[bundleFile:9.4.57.v20241219]
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) ~[bundleFile:9.4.57.v20241219]
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) ~[bundleFile:9.4.57.v20241219]
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) ~[bundleFile:9.4.57.v20241219]
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409) ~[bundleFile:9.4.57.v20241219]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) ~[bundleFile:9.4.57.v20241219]
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) ~[bundleFile:9.4.57.v20241219]
at java.lang.Thread.run(Thread.java:1583) [?:?]
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private java.lang.String java.lang.Throwable.detailMessage accessible: module java.base does not "opens java.lang" to unnamed module @1a243b32
at java.lang.reflect.AccessibleObject.throwInaccessibleObjectException(AccessibleObject.java:391) ~[?:?]
at java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:367) ~[?:?]
at java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:315) ~[?:?]
at java.lang.reflect.Field.checkCanSetAccessible(Field.java:183) ~[?:?]
at java.lang.reflect.Field.setAccessible(Field.java:177) ~[?:?]
at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:68) ~[?:?]
@andrea636 the essential message from your log is the one below “The authorization request is still pending” this means that you did not complete the login process on the Tado website. Perhaps because you used the wrong login credentials, or perhaps because you did not press the submit button.
2025-04-08 12:09:31.849 [TRACE] [lient.internal.OAuthConnectorRFC8628] - fetchAccessTokenResponse() response: {"error":"authorization_pending","error_description":"The authorization request is still pending"}
The sequence of screens that you should see is as follows..
OpenHAB Servlet
Tado Enter User Code Page
Tado Signin Page
Tado Success Page
I can’t reach the page with submit button (Tado User Code Page) , when I click on “click to authenticate” in the Openhab Servlet page the browser give me the error below
As mentioned above, your refresh token is trashed, so you need to manually edit the storage json file and remove the tado.home entries.
When you have deleted all tado.home entries, then turn on log:set TRACE org.openhab.core.auth please. The HTTP 500 error does not help me.
After I deleted all tado:home entries in StorageHandler.For.OAuthClientService.json :
AUTH log
2025-04-10 02:20:21.985 [TRACE] [lient.internal.OAuthConnectorRFC8628] - getDeviceCodeResponse() start..
2025-04-10 02:20:21.985 [TRACE] [lient.internal.OAuthConnectorRFC8628] - getDeviceCodeResponse() loaded from service: AccessTokenResponse [null]
2025-04-10 02:20:21.999 [TRACE] [lient.internal.OAuthConnectorRFC8628] - fetchDeviceCodeResponse() request: https://login.tado.com/oauth2/device_authorize?client_id=1bb50063-6b0c-4d11-bd99-387f4a91cc46&scope=offline_access
2025-04-10 02:20:22.150 [TRACE] [lient.internal.OAuthConnectorRFC8628] - fetchDeviceCodeResponse() response: {"device_code":"osBnDay0LJRGAO_gO0pFIFAzpa6JnIy7cAPcKy_SHeE","expires_in":300,"interval":5,"user_code":"CQGCKR","verification_uri":"https://login.tado.com/oauth2/device","verification_uri_complete":"https://login.tado.com/oauth2/device?user_code=CQGCKR"}
2025-04-10 02:20:22.150 [TRACE] [lient.internal.OAuthConnectorRFC8628] - fetchDeviceCodeResponse() return: DeviceCodeResponseDTO [deviceCode=osBnDay0LJRGAO_gO0pFIFAzpa6JnIy7cAPcKy_SHeE, expiresIn=300, interval=5, userCode=CQGCKR, verificationUri=https://login.tado.com/oauth2/device, verificationUriComplete=https://login.tado.com/oauth2/device?user_code=CQGCKR, createdOn=2025-04-10T00:20:22.150552200Z]
2025-04-10 02:20:22.150 [TRACE] [lient.internal.OAuthConnectorRFC8628] - getDeviceCodeResponse() fetched from remote: DeviceCodeResponseDTO [deviceCode=osBnDay0LJRGAO_gO0pFIFAzpa6JnIy7cAPcKy_SHeE, expiresIn=300, interval=5, userCode=CQGCKR, verificationUri=https://login.tado.com/oauth2/device, verificationUriComplete=https://login.tado.com/oauth2/device?user_code=CQGCKR, createdOn=2025-04-10T00:20:22.150552200Z]
2025-04-10 02:20:22.150 [TRACE] [lient.internal.OAuthConnectorRFC8628] - fetchAccessTokenResponse() request: https://login.tado.com/oauth2/token?client_id=1bb50063-6b0c-4d11-bd99-387f4a91cc46&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=osBnDay0LJRGAO_gO0pFIFAzpa6JnIy7cAPcKy_SHeE
2025-04-10 02:20:22.244 [TRACE] [lient.internal.OAuthConnectorRFC8628] - fetchAccessTokenResponse() response: {"error":"authorization_pending","error_description":"The authorization request is still pending"}
TADO log
2025-04-10 02:19:50.516 [DEBUG] [ernal.discovery.TadoDiscoveryService] - Start Tado background discovery
2025-04-10 02:19:50.517 [DEBUG] [ernal.discovery.TadoDiscoveryService] - Start Scan
2025-04-10 02:19:50.525 [TRACE] [ado.internal.handler.TadoHomeHandler] - initialize() api v2 created
2025-04-10 02:20:06.880 [DEBUG] [ado.internal.handler.TadoHomeHandler] - Error accessing tado server: java.util.concurrent.ExecutionException: org.eclipse.jetty.client.HttpResponseException: HTTP protocol violation: Authentication challenge without WWW-Authenticate header
I finally solved the error below
I add this string set.JDK_JAVA_OPTIONS=–add-opens=java.base/java.lang=ALL-UNNAMED in the openhab-wrapper.conf file as here :
#*******************************************************
# openHAB-wrapper.conf for Windows Service Installation
#*******************************************************
# openHAB installation dir (Adapt this first setting to your system)
set.default.OPENHAB_HOME=C:\openHAB
set.JDK_JAVA_OPTIONS=--add-opens=java.base/java.lang=ALL-UNNAMED
# Wrapper Properties
@andrea636 many thanks for the log.
It shows the start of a normal authentication process. Your system is fetching a user code and a device code with a validity of 300 seconds, and a polling interval of 5 seconds. It does the first poll, which returns correctly a pending error, and the servlet would then forward you to the Tado login page. But the issue is that the GSON parser on your system fails to parse the pending error and instead throws the exception that you posted previously. And this kills the rest of the login process.
So the issue is the GSON parser failing.
The strange thing is that I have tested this on my operative OH systems on v4.3.x and v5.x both on Linux and Windows and both with Java 17 and 21, on three different machines, and in none of those cases does the GSON parser throw this error. However I did manage to set up a rudimentary Junit test in Eclipse where I could force such a GSON parse error. But honestly I have no idea why there is this variability.
The actual GSON error stems from Java Reflection being unable to access a particular unused private data field, so it may perhaps be something to do with the flavour of Java that you are running on, and/or your runtime environment.
Anyway the conclusion is that I have made some changes in OH core with a custom parser for the error messages, that should avoid the GSON Reflection error. This has been merged into OH core where it will appear in the next OH v5.x Snaphot and possibly eventually in a next v4.3.5 patch, but I have no idea of the OH release cycle for the latter.
—-
EDIT: my message crossed with yours above. And it confirms that there is some oddity in the JRE .. so as a matter of interest perhaps you can explain why that option would have fixed this issue? It beats me..
I don’t know how this string in the wrapper.conf fix the problem. I searched for a solution on many sites and i when I saw these two I try ..
After reading these two sites I only tried with the string set.JDK_JAVA_OPTIONS=–add-opens=java.base/java.lang=ALL-UNNAMED
The issue concerns deep reflection. The OH OAuth error class is a descendent of the Throwable class which is within the Java core. When GSON deserializes an error message it uses reflection to set the class field. And since the class is a descendent of Java core that requires deep reflection. Prior to Java v9 deep reflection was perfectly Ok. But thereafter – on some installations – it was forbidden. This means that the bug has been present and undiscovered since Java 9, and you seem to be the unlucky one whose installation forbids deep reflection. But the good news is that we have now two solutions – namely your option setting that reenables deep reflection on your system, and my solution in Java code that instantiates the error class object by a means that does not require deep reflection.
I also had issues with stopping bindings every few hours. I copied you latest jar file and everything works fine again since the last 2 days. Thank you very much for you effort @AndrewFG !
I received the same message after restoring Openhab on another device from a backup.
Deleting the complete entry for “tado:home.AccessTorkenResponse”: …}” in \OPENHABIAN\openHAB-userdata\jsondb\StorageHandler.For.OAuthClientService.json solved the problem for me as well.
https://discourse.openhab.org/t/tado-authentication/163276/52
This solves the problem for me. Seems that there were broken/outdated tokens in the json file. Just kicked out every key with “tado:home”, restarted openhab and went to /tado to authenticate.
Hi,
I’m experiencing an issue, possibly related to GSON.
When I try to open http://192.168.10.118:8080/tado
, I see the following message:
“Status: OAuthClientService errornull”.
Here are the logs:
2025-06-16 09:49:31.352 [ERROR] [oauth2client.internal.OAuthConnector] - grant type refresh_token to URL https://login.tado.com/oauth2/token failed with error code invalid_grant, description The refresh_token is invalid.
2025-06-16 09:49:31.355 [DEBUG] [.internal.handler.TadoHandlerFactory] - getAccessTokenResponse() error null
org.openhab.core.auth.client.oauth2.OAuthResponseException: null
at org.openhab.core.auth.oauth2client.internal.OAuthConnector.lambda$0(OAuthConnector.java:96) ~[?:?]
at com.google.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:76) ~[?:?]
at com.google.gson.Gson.fromJson(Gson.java:1227) ~[?:?]
at com.google.gson.Gson.fromJson(Gson.java:1137) ~[?:?]
at com.google.gson.Gson.fromJson(Gson.java:1047) ~[?:?]
at com.google.gson.Gson.fromJson(Gson.java:982) ~[?:?]
at org.openhab.core.auth.oauth2client.internal.OAuthConnector.doRequest(OAuthConnector.java:368) ~[?:?]
at org.openhab.core.auth.oauth2client.internal.OAuthConnector.grantTypeRefreshToken(OAuthConnector.java:227) ~[?:?]
at org.openhab.core.auth.oauth2client.internal.OAuthClientServiceImpl.refreshTokenInner(OAuthClientServiceImpl.java:336) ~[?:?]
at org.openhab.core.auth.oauth2client.internal.OAuthClientServiceImpl.getAccessTokenResponse(OAuthClientServiceImpl.java:377) ~[?:?]
at org.openhab.binding.tado.internal.handler.TadoHandlerFactory.getAccessTokenResponse(TadoHandlerFactory.java:205) ~[?:?]
at org.openhab.binding.tado.internal.servlet.TadoAuthenticationServlet.serveStatusPage(TadoAuthenticationServlet.java:109) ~[?:?]
at org.openhab.binding.tado.internal.servlet.TadoAuthenticationServlet.doGet(TadoAuthenticationServlet.java:83) ~[?:?]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:497) ~[bundleFile:4.0.4]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:584) ~[bundleFile:4.0.4]
at org.ops4j.pax.web.service.spi.servlet.OsgiInitializedServlet.service(OsgiInitializedServlet.java:102) ~[bundleFile:?]
at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1450) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1656) ~[bundleFile:9.4.54.v20240208]
at org.ops4j.pax.web.service.spi.servlet.OsgiFilterChain.doFilter(OsgiFilterChain.java:113) ~[bundleFile:?]
at org.ops4j.pax.web.service.jetty.internal.PaxWebServletHandler.doHandle(PaxWebServletHandler.java:334) ~[bundleFile:?]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:234) ~[bundleFile:9.4.54.v20240208]
at org.ops4j.pax.web.service.jetty.internal.PrioritizedHandlerCollection.handle(PrioritizedHandlerCollection.java:96) ~[bundleFile:?]
at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:731) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.Server.handle(Server.java:516) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487) ~[bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732) [bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479) [bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) [bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) [bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) [bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) [bundleFile:9.4.54.v20240208]
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) [bundleFile:9.4.54.v20240208]
at java.lang.Thread.run(Thread.java:833) [?:?]
When OH tried to refresh your authentication token, the Tado authentication server returned an HTTP 400 error. HTTP 400 means “bad request” – this probably means that the Tado server considers the refresh token associated with your authentication token to be invalid.
Perhaps you have been playing around with the tokens and may have created a new token on a different OH instance? Or something like that.
Anyway, probably your best solution is to start again from scratch. You may need to clear the token from the OH storage handler as described a couple of posts above this.
EDIT the bit about the GSON is actually not an error; it is just that the way the binding logs the real error makes it look like something to do with the JSON. The first line of the log ERROR message says it all..
2025-06-16 09:49:31.352 [ERROR] [oauth2client.internal.OAuthConnector] - grant type refresh_token to URL https://login.tado.com/oauth2/token failed with error code invalid_grant, description The refresh_token is invalid.
This makes me wonder…
I came across this article about creating a tado schedule via python a while ago, and it’s on my to do list. But I now realize the first part is no longer valid, since the authentication method has change.
But your above remark seems to suggest that it’s not a good idea to toy around with authentication tokens… Could you elaborate some more on how this token business works? (Or, if that’s possible: what you would recommend in order to make that python code work without breaking the openHAB binding?)
Tado uses RFC8628 authentication which works als follows:
- user authenticates themself via a web page interaction; server provides a device code
- application (OH) presents device code to server within a short period; server provides an authentication token and a refresh token
- application uses authentication token to read/write the device status; until authentication token expires
- application presents the refresh token; server provides new authentication token and refresh token; go to 3.
Your issue is that at step 4. the Tado server considers the refresh token from step 2. or 4. to be invalid. This would normally never happen unless something else would have done step 4. outside of the above sequence.