[Jellyfin} Client configuration and API errors

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

Sorry editor displayed

/jellyfin/
in a blockquote as

/jellyfin/

now corrected in original post