tauri-apps/tauri · error · JSONException

Not all items are instances of the given type

Error message

Not all items are instances of the given type

What it means

The Kotlin `JSArray.toList<E>()` extension casts each JSONArray element to `E`; if any element is not an instance of the requested type, it throws a `JSONException` with this message. It protects Android plugin IPC from receiving arrays of unexpected element types.

Solutions

  1. Inspect the plugin command signature in the Kotlin handler and send exactly that element type from JS/Rust.
  2. Remove null/undefined entries from the array before invoking (e.g. `args.filter(a => a != null)`).
  3. If the plugin API changed, update both the Kotlin plugin and the frontend bindings to the same version.
  4. Catch `JSONException` on the Kotlin side (or use `opt(i)`/manual conversion) if you need tolerant parsing.

Example fix

// before
invoke('plugin:fs|read', { paths: [null, '/a.txt'] })
// after
invoke('plugin:fs|read', { paths: ['/a.txt'] }) // all elements match handler's List<String>
Defensive patterns

Strategy: type-guard

Validate before calling

function assertStringArray(arr) {
  if (!Array.isArray(arr) || arr.some(a => typeof a !== 'string'))
    throw new TypeError('expected array of strings');
}

Type guard

function isStringArray(v) {
  return Array.isArray(v) && v.every(x => typeof x === 'string');
}

Try / catch

// Kotlin side, tolerant parse
val items = try { arr.toList<String>() } catch (e: JSONException) { emptyList() }

Prevention

When it happens

Trigger: Invoking an Android plugin command whose JS argument array contains elements that cannot be cast to the Kotlin type declared by the handler (e.g. sending objects where the handler expects strings, or nulls).

Common situations: JS/Rust side passing mixed-type arrays, nulls, or nested objects to plugin commands; plugin signature changed after an upgrade while frontend still sends the old argument shape.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at crates/tauri/mobile/android/src/main/java/app/tauri/plugin/JSArray.kt:26

import org.json.JSONException

class JSArray : JSONArray {
  constructor() : super() {}
  constructor(json: String?) : super(json) {}
  constructor(copyFrom: Collection<*>?) : super(copyFrom) {}
  constructor(array: Any?) : super(array) {}

  @Suppress("UNCHECKED_CAST", "ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE")
  @Throws(JSONException::class)
  fun <E> toList(): List<E> {
    val items: MutableList<E> = ArrayList()
    var o: Any? = null
    for (i in 0 until this.length()) {
      this.get(i).also { o = it }
      try {
        items.add(this.get(i) as E)
      } catch (ex: Exception) {
        throw JSONException("Not all items are instances of the given type")
      }
    }
    return items
  }

  companion object {
    /**
     * Create a new JSArray without throwing a error
     */
    fun from(array: Any?): JSArray? {
      try {
        return JSArray(array)
      } catch (ex: JSONException) {
        //
      }
      return null
    }
  }

View on GitHub (pinned to 460ec35447)