Skip to content

Suwayomi-JUI cannot deserialize download info #1692

@ypoluektovich

Description

@ypoluektovich

Steps to reproduce

  1. Connect to the server with Suwayomi-JUI
  2. Attempt to download a manga

Expected behavior

The chapter should get downloaded, and the progress of the download should appear in the "downloads" tab.

Actual behavior

The download isn't starting, and the logs are flooded with error messages.

On the server side:

Oct 02 22:27:47 echo suwayomi-server[1372]: 22:27:47.678 [DefaultDispatcher-worker-13] ERROR suwayomi.tachidesk.server.ServerSetup -- unhandled exception
Oct 02 22:27:47 echo suwayomi-server[1372]: java.io.IOException: java.nio.channels.ClosedChannelException
Oct 02 22:27:47 echo suwayomi-server[1372]:         at org.eclipse.jetty.util.FutureCallback.block(FutureCallback.java:163)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at org.eclipse.jetty.util.FutureCallback.block(FutureCallback.java:139)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at org.eclipse.jetty.websocket.common.JettyWebSocketRemoteEndpoint.sendBlocking(JettyWebSocketRemoteEndpoint.java:191)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at org.eclipse.jetty.websocket.common.JettyWebSocketRemoteEndpoint.sendString(JettyWebSocketRemoteEndpoint.java:52)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at io.javalin.websocket.WsContext.send(WsContext.kt:48)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at io.javalin.websocket.WsContext.sendAsClass(WsContext.kt:45)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at io.javalin.websocket.WsContext.send(WsContext.kt:42)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at suwayomi.tachidesk.manga.impl.download.DownloadManager$notifyAllClients$2.invokeSuspend(DownloadManager.kt:200)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:829)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704)
Oct 02 22:27:47 echo suwayomi-server[1372]:         Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: null
Oct 02 22:27:47 echo suwayomi-server[1372]: Caused by: java.nio.channels.ClosedChannelException: null
Oct 02 22:27:47 echo suwayomi-server[1372]:         at org.eclipse.jetty.websocket.core.internal.WebSocketSessionState.onOutgoingFrame(WebSocketSessionState.java:184)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at org.eclipse.jetty.websocket.core.internal.WebSocketCoreSession.sendFrame(WebSocketCoreSession.java:514)
Oct 02 22:27:47 echo suwayomi-server[1372]:         at org.eclipse.jetty.websocket.common.JettyWebSocketRemoteEndpoint.sendBlocking(JettyWebSocketRemoteEndpoint.java:190)
Oct 02 22:27:47 echo suwayomi-server[1372]:         ... 11 common frames omitted

On the client side:

[DefaultDispatcher-worker-5] WARN/WebsocketService: Error running websocket
kotlinx.serialization.MissingFieldException: Fields [chapter, manga] are required for type with serial name 'ca.gosyer.jui.domain.download.model.DownloadChapter', but they were missing at path: $.queue[0]
	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:95) ~[kotlinx-serialization-json-jvm-1.6.3-f748e5e9c7239a8197747ced7208c13.jar:?]
	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43) ~[kotlinx-serialization-core-jvm-1.6.3-a53de86f751fdde057be40958fad42ac.jar:1.6.3]
	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70) ~[kotlinx-serialization-core-jvm-1.6.3-a53de86f751fdde057be40958fad42ac.jar:1.6.3]
	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168) ~[kotlinx-serialization-json-jvm-1.6.3-f748e5e9c7239a8197747ced7208c13.jar:?]
	at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:538) ~[kotlinx-serialization-core-jvm-1.6.3-a53de86f751fdde057be40958fad42ac.jar:1.6.3]
	at kotlinx.serialization.internal.CollectionLikeSerializer.readElement(CollectionSerializers.kt:80) ~[kotlinx-serialization-core-jvm-1.6.3-a53de86f751fdde057be40958fad42ac.jar:1.6.3]
	at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51) ~[kotlinx-serialization-core-jvm-1.6.3-a53de86f751fdde057be40958fad42ac.jar:1.6.3]
	at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36) ~[kotlinx-serialization-core-jvm-1.6.3-a53de86f751fdde057be40958fad42ac.jar:1.6.3]
	at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43) ~[kotlinx-serialization-core-jvm-1.6.3-a53de86f751fdde057be40958fad42ac.jar:1.6.3]
	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69) ~[kotlinx-serialization-json-jvm-1.6.3-f748e5e9c7239a8197747ced7208c13.jar:?]
	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43) ~[kotlinx-serialization-core-jvm-1.6.3-a53de86f751fdde057be40958fad42ac.jar:1.6.3]
	at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70) ~[kotlinx-serialization-core-jvm-1.6.3-a53de86f751fdde057be40958fad42ac.jar:1.6.3]
	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableElement(StreamingJsonDecoder.kt:168) ~[kotlinx-serialization-json-jvm-1.6.3-f748e5e9c7239a8197747ced7208c13.jar:?]
	at ca.gosyer.jui.domain.download.model.DownloadStatus$$serializer.deserialize(DownloadStatus.kt:12) ~[domain-desktop-1.3.3-8defd56f388ed9d632a3ca7dca2e392.jar:?]
	at ca.gosyer.jui.domain.download.model.DownloadStatus$$serializer.deserialize(DownloadStatus.kt:12) ~[domain-desktop-1.3.3-8defd56f388ed9d632a3ca7dca2e392.jar:?]
	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69) ~[kotlinx-serialization-json-jvm-1.6.3-f748e5e9c7239a8197747ced7208c13.jar:?]
	at kotlinx.serialization.json.Json.decodeFromString(Json.kt:107) ~[kotlinx-serialization-json-jvm-1.6.3-f748e5e9c7239a8197747ced7208c13.jar:?]
	at ca.gosyer.jui.domain.download.service.DownloadService.onReceived(DownloadService.kt:59) ~[domain-desktop-1.3.3-8defd56f388ed9d632a3ca7dca2e392.jar:?]
	at ca.gosyer.jui.domain.base.WebsocketService$init$1$1$2$1.invoke(WebsocketService.kt:73) ~[domain-desktop-1.3.3-8defd56f388ed9d632a3ca7dca2e392.jar:?]
	at ca.gosyer.jui.domain.base.WebsocketService$init$1$1$2$1.invoke(WebsocketService.kt:73) ~[domain-desktop-1.3.3-8defd56f388ed9d632a3ca7dca2e392.jar:?]
	at kotlinx.coroutines.flow.FlowKt__MergeKt$mapLatest$1.invokeSuspend(Merge.kt:213) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.flow.FlowKt__MergeKt$mapLatest$1.invoke(Merge.kt) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.flow.FlowKt__MergeKt$mapLatest$1.invoke(Merge.kt) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3$1$2.invokeSuspend(Merge.kt:30) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3$1$2.invoke(Merge.kt) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3$1$2.invoke(Merge.kt) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.intrinsics.UndispatchedKt.startCoroutineUndispatched(Undispatched.kt:27) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:90) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:123) [kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:52) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.BuildersKt.launch(Unknown Source) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:43) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3$1.emit(Merge.kt:29) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at ca.gosyer.jui.domain.base.WebsocketService$init$1$1$2$invokeSuspend$$inlined$filterIsInstance$1$2.emit(Emitters.kt:219) ~[domain-desktop-1.3.3-8defd56f388ed9d632a3ca7dca2e392.jar:?]
	at kotlinx.coroutines.flow.FlowKt__ChannelsKt.emitAllImpl$FlowKt__ChannelsKt(Channels.kt:33) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.flow.FlowKt__ChannelsKt.access$emitAllImpl$FlowKt__ChannelsKt(Channels.kt:1) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.flow.ChannelAsFlow.collect(Channels.kt:125) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at ca.gosyer.jui.domain.base.WebsocketService$init$1$1$2$invokeSuspend$$inlined$filterIsInstance$1.collect(SafeCollector.common.kt:112) ~[domain-desktop-1.3.3-8defd56f388ed9d632a3ca7dca2e392.jar:?]
	at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3.invokeSuspend(Merge.kt:23) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3.invoke(Merge.kt) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3.invoke(Merge.kt) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:61) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:261) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest.flowCollect(Merge.kt:21) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.flow.internal.ChannelFlowOperator.collectTo$suspendImpl(ChannelFlow.kt:153) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.flow.internal.ChannelFlowOperator.collectTo(ChannelFlow.kt) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.flow.internal.ChannelFlow$collectToFun$1.invokeSuspend(ChannelFlow.kt:56) ~[kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) [kotlin-stdlib-2.0.0-Beta4-85f31b1753677754b114fd3b1beae3.jar:2.0.0-Beta4-release-16]
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:104) [kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:585) [kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:802) [kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:706) [kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:693) [kotlinx-coroutines-core-jvm-1.8.0-d2920b1d99a82fafcceabc3a48f7e0.jar:?]
Caused by: kotlinx.serialization.MissingFieldException: Fields [chapter, manga] are required for type with serial name 'ca.gosyer.jui.domain.download.model.DownloadChapter', but they were missing
	at kotlinx.serialization.internal.PluginExceptionsKt.throwMissingFieldException(PluginExceptions.kt:20) ~[kotlinx-serialization-core-jvm-1.6.3-a53de86f751fdde057be40958fad42ac.jar:1.6.3]
	at ca.gosyer.jui.domain.download.model.DownloadChapter.<init>(DownloadChapter.kt:14) ~[domain-desktop-1.3.3-8defd56f388ed9d632a3ca7dca2e392.jar:?]
	at ca.gosyer.jui.domain.download.model.DownloadChapter$$serializer.deserialize(DownloadChapter.kt:14) ~[domain-desktop-1.3.3-8defd56f388ed9d632a3ca7dca2e392.jar:?]
	at ca.gosyer.jui.domain.download.model.DownloadChapter$$serializer.deserialize(DownloadChapter.kt:14) ~[domain-desktop-1.3.3-8defd56f388ed9d632a3ca7dca2e392.jar:?]
	at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:69) ~[kotlinx-serialization-json-jvm-1.6.3-f748e5e9c7239a8197747ced7208c13.jar:?]
	... 53 more

Suwayomi-Server version

2.1.1947

Used database

H2

Server operating system

freshly updated Arch Linux

Server Desktop Environment

i3

Server JVM version

openjdk 21.0.8 2025-07-15

Used client name

Suwayomi-JUI

Client version

1.3.3

Used web browser

n/a

Client operating system

freshly updated Arch Linux

Other details

The regression appeared after updating the server from version 2.1.1941-1.3 to 2.1.1947-1.3 as packaged in https://aur.archlinux.org/packages/suwayomi-server-preview-bin

Acknowledgements

  • I have searched the existing issues and this is a new ticket, NOT a duplicate or related to another open or closed issue.
  • I have written a short but informative title (ideally less than ~100 characters).
  • I have tried the troubleshooting guide described in README.md
  • I have updated to the latest version.
  • I have filled out all of the requested information in this form, including specific version numbers.
  • I understand that Suwayomi does not have or fix any extensions, and I will not receive help for any issues related to sources or extensions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions