tauri-apps/tauri · error · DecodingError

missing userInfo for Channel handler. This is a Tauri issue

Error message

missing userInfo for Channel handler. This is a Tauri issue

What it means

When decoding a Channel on iOS, Tauri reads the callback handler (a (UInt64, String) -> Void closure) from the decoder's userInfo under channelDataKey. If it is missing, the decoder was invoked without the userInfo entry Tauri's own infrastructure always supplies, so the code declares it a Tauri-internal bug and throws this DecodingError.

Solutions

  1. Decode Channel-bearing payloads only through Tauri's normal IPC deserialization path, not a standalone JSONDecoder you create.
  2. If you must decode manually, set decoder.userInfo[channelDataKey] to a (UInt64, String) -> Void handler before calling decode.
  3. Update the iOS Tauri API dependency, since the message indicates an internal invariant break that may already be fixed upstream.
  4. Report it to the Tauri repository with a reproducing plugin/webview setup if it occurs in stock usage.

Example fix

// before
let decoder = JSONDecoder()
let value = try decoder.decode(MyArgs.self, from: data)
// after: reuse Tauri's decoder that carries the channel handler
let value = try tauriProvidedDecoder.decode(MyArgs.self, from: data)
Defensive patterns

Strategy: type-guard

Validate before calling

guard let handler = decoder.userInfo[Channel.channelDataKey] as? (UInt64, String) -> Void else { fatalError("decode via Tauri IPC path") }

Type guard

let hasChannelHandler: (JSONDecoder) -> Bool = { $0.userInfo[Channel.channelDataKey] is (UInt64, String) -> Void }

Try / catch

do {
  let value = try decoder.decode(MyArgs.self, from: data)
} catch let DecodingError.dataCorruptedError(_, _, desc) where desc.contains("userInfo") {
  // fall back to Tauri-provided decoder
}

Prevention

When it happens

Trigger: Decoding a Channel with a JSONDecoder instance that was not set up by Tauri's IPC layer — i.e. decoder.userInfo[channelDataKey] contains no (UInt64, String) handler.

Common situations: Manually constructing a JSONDecoder and decoding a type containing a Channel in plugin code, calling decode outside the normal IPC dispatch path, or a Tauri version regression in the mobile API layer.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of tauri-apps/tauri@460ec35447 (2026-09-18). Data as JSON: /api/errors/a3684abf7a4d699f. Report an issue: GitHub.

Appendix: source

Thrown at crates/tauri/mobile/ios-api/Sources/Tauri/Channel.swift:34

    let channelDef = try container.decode(String.self)

    let components = channelDef.components(separatedBy: CHANNEL_PREFIX)
    if components.count < 2 {
      throw DecodingError.dataCorruptedError(
        in: container,
        debugDescription: "Invalid channel definition from \(channelDef)"
      )

    }
    guard let channelId = UInt64(components[1]) else {
      throw DecodingError.dataCorruptedError(
        in: container,
        debugDescription: "Invalid channel ID from \(channelDef)"
      )
    }

    guard let handler = decoder.userInfo[channelDataKey] as? (UInt64, String) -> Void else {
      throw DecodingError.dataCorruptedError(
        in: container,
        debugDescription: "missing userInfo for Channel handler. This is a Tauri issue"
      )
    }

    self.id = channelId
    self.handler = handler
  }

  func serialize(_ data: JsonValue) -> String {
    do {
      return try data.jsonRepresentation() ?? "\"Failed to serialize payload\""
    } catch {
      return "\"\(error)\""
    }
  }

  public func send(_ data: JsonObject) {

View on GitHub (pinned to 460ec35447)