Openhab and Addons 5.0.2 Debian 12 (bookworm) AMD6
Jellyfin Server 10.10.7 on Rpi3 Raspbian 11 (bullseye)
The Jellyfin binding automatically discovered the server but not any clients.
Then I tried to find the authentication credentials (userId and token) for the user that the binding will use to interact with the server” using
<local openHAB server url>/jellyfin/<server thing id>
This opened a login dialog, which I completed using the Jellyfin user created with Remote Control permissions, but this returned no authentication data.
So I then interrogated the jellyfin.db Devices table on the Jellyfin server using sqlite3 to obtain the userId and tokenneeded and configured a Jellyfin server thing.
This came online.
But I have not managed to get a Jellyfin client up and running.
As I said no clients are discovered by a scan. so i created a Things file.
Thing jellyfin:client:exampleServerId:<JELLYFIN_DEVICE_ID> "Jellyfin Web client" (jellyfin:server:exampleServerId)
Where I used:
Jellyfin server Openhab ThingId as exampleServerId
DeviceId found via sqlite3 to use as the <JELLYFIN_DEVICE_ID>
This is the actual line from my Things file f(or a web client on Windows 11):
Thing jellyfin:client:8d78b2a191c40cc985d0bbfdf4a7e14:TW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzE0MS4wLjAuMCBTYWZhcmkvNTM3LjM2fDE3NjE5OTk2NDIyMTM1 "windows_JFC" (jellyfin:server:88d78b2a191c40cc985d0bbfdf4a7e14)
The windows_JFC thing is created with Status UNKNOWN.
The openhab.log goes wild as the Jellyfin client thing is created:
2025-11-05 10:45:14.722 [ERROR] [.jellyfin.sdk.api.client.RawResponse] - Deserialization failed
kotlinx.serialization.MissingFieldException: Fields [SupportsContentUploading, SupportsSync] are required for type with serial name 'org.jellyfin.sdk.model.api.ClientCapabilities', but they were missing at path: $[0].Capabilities
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:95) ~[bundleFile:?]
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43) ~[bundleFile:?]
at kotlinx.serialization.encoding.AbstractDecoder.decodeNullableSerializableElement(AbstractDecoder.kt:78) ~[bundleFile:?]
at org.jellyfin.sdk.model.api.SessionInfo$$serializer.deserialize(SessionInfo.kt:27) ~[bundleFile:?]
at org.jellyfin.sdk.model.api.SessionInfo$$serializer.deserialize(SessionInfo.kt:27) ~[bundleFile:?]
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69) ~[bundleFile:?]
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43) ~[bundleFile:?]
at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70) ~[bundleFile:?]
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168) ~[bundleFile:?]
at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538) ~[bundleFile:?]
at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80) ~[bundleFile:?]
at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51) ~[bundleFile:?]
at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36) ~[bundleFile:?]
at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43) ~[bundleFile:?]
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69) ~[bundleFile:?]
at kotlinx.serialization.json.Json.decodeFromString(Json.kt:107) ~[bundleFile:?]
at org.jellyfin.sdk.api.operations.SessionApi.getSessions(SessionApi.kt:509) [bundleFile:?]
at org.jellyfin.sdk.api.operations.SessionApi$getSessions$1.invokeSuspend(SessionApi.kt) [bundleFile:?]
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:191) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:147) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(SuspendFunctionGun.kt:15) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:93) [bundleFile:?]
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:191) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:147) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(SuspendFunctionGun.kt:15) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:93) [bundleFile:?]
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:191) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:147) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(SuspendFunctionGun.kt:15) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:93) [bundleFile:?]
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(SuspendFunctionGun.kt:191) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:147) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(SuspendFunctionGun.kt:15) [bundleFile:?]
at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(SuspendFunctionGun.kt:93) [bundleFile:?]
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46) [bundleFile:?]
at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:175) [bundleFile:?]
at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:164) [bundleFile:?]
at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:470) [bundleFile:?]
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:504) [bundleFile:?]
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:493) [bundleFile:?]
at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:364) [bundleFile:?]
at kotlinx.coroutines.ResumeAwaitOnCompletion.invoke(JobSupport.kt:1403) [bundleFile:?]
at kotlinx.coroutines.JobSupport.notifyCompletion(JobSupport.kt:1492) [bundleFile:?]
at kotlinx.coroutines.JobSupport.completeStateFinalization(JobSupport.kt:322) [bundleFile:?]
at kotlinx.coroutines.JobSupport.finalizeFinishingState(JobSupport.kt:239) [bundleFile:?]
at kotlinx.coroutines.JobSupport.tryMakeCompletingSlowPath(JobSupport.kt:907) [bundleFile:?]
at kotlinx.coroutines.JobSupport.tryMakeCompleting(JobSupport.kt:864) [bundleFile:?]
at kotlinx.coroutines.JobSupport.makeCompletingOnce$kotlinx_coroutines_core(JobSupport.kt:829) [bundleFile:?]
at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:97) [bundleFile:?]
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46) [bundleFile:?]
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104) [bundleFile:?]
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:585) [bundleFile:?]
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:802) [bundleFile:?]
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:706) [bundleFile:?]
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:693) [bundleFile:?]
Caused by: kotlinx.serialization.MissingFieldException: Fields [SupportsContentUploading, SupportsSync] are required for type with serial name 'org.jellyfin.sdk.model.api.ClientCapabilities', but they were missing
at kotlinx.serialization.internal.PluginExceptionsKt.throwMissingFieldException(PluginExceptions.kt:20) ~[bundleFile:?]
at org.jellyfin.sdk.model.api.ClientCapabilities.<init>(ClientCapabilities.kt:14) ~[bundleFile:?]
at org.jellyfin.sdk.model.api.ClientCapabilities$$serializer.deserialize(ClientCapabilities.kt:14) ~[bundleFile:?]
at org.jellyfin.sdk.model.api.ClientCapabilities$$serializer.deserialize(ClientCapabilities.kt:14) ~[bundleFile:?]
at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69) ~[bundleFile:?]
... 58 more
Within the Jellyfin server there is scope for creating an API key but the Openhab Jellyfin binding does not mention the need for this API key as far as I can tell.
Any pointers as to what I am doing wrong?
Thanks in advance.
Stephen