tauri-apps/tauri · error · DecodingError

Invalid channel definition from \(channelDef)

Error message

Invalid channel definition from \(channelDef)

What it means

The iOS Swift `Channel` type decodes a channel definition string of the form `<CHANNEL_PREFIX><id>` (e.g. `__CHANNEL__:<id>`). If the decoded string lacks the prefix separator or has no ID part, `init(from:)` throws a `DecodingError.dataCorrupted` with this message.

Solutions

  1. Ensure the tauri iOS API Swift package version matches the tauri core version so channel prefixes agree.
  2. Always pass a real `Channel`/`__CHANNEL__` object from JS/Rust rather than an arbitrary string.
  3. Check the invoke payload serialization — the channel definition must include both prefix and numeric ID.
  4. Catch/handle `DecodingError.dataCorrupted` in custom Swift plugin code to log the offending `channelDef`.

Example fix

// before
plugin.call('watch', { onEvent: '__CHANNEL__' }) // missing id
// after
plugin.call('watch', { onEvent: channel }) // real Channel object -> "__CHANNEL__:<id>"
Defensive patterns

Strategy: type-guard

Validate before calling

// Swift: validate channel definition shape before decode
func isValidChannelDef(_ s: String, prefix: String) -> Bool {
  guard s.hasPrefix(prefix),
        let id = s.dropFirst(prefix.count).split(separator: ":").last,
        UInt64(id) != nil else { return false }
  return true
}

Type guard

func asValidChannel(_ s: String) -> Channel? {
  isValidChannelDef(s, prefix: CHANNEL_PREFIX) ? nil : nil // use forced decode in do/catch
}

Try / catch

// Swift
do {
  let channel = try JSONDecoder().decode(Channel.self, from: data)
} catch DecodingError.dataCorrupted(let ctx) {
  print("bad channel definition: \(ctx.debugDescription)")
}

Prevention

When it happens

Trigger: Rust/JS passes a channel identifier string to Swift plugin code that does not match the expected `<prefix><id>` format — empty string, wrong prefix, or only the prefix with no numeric ID.

Common situations: Mismatched tauri core and iOS API (Swift Package) versions where the channel prefix format changed; hand-crafted invoke arguments passing raw strings instead of `Channel` objects; channel serialization dropping the ID.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

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

// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

import Foundation

let CHANNEL_PREFIX = "__CHANNEL__:"
let channelDataKey = CodingUserInfoKey(rawValue: "sendChannelData")!

public class Channel: Decodable {
  public let id: UInt64
  let handler: (UInt64, String) -> Void

  public required init(from decoder: Decoder) throws {
    let container = try decoder.singleValueContainer()
    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"
      )
    }

View on GitHub (pinned to 460ec35447)