{"record":{"id":"b4f2fa05f6847634","repo":"tauri-apps/tauri","slug":"not-all-items-are-instances-of-the-given-type","errorCode":null,"errorMessage":"Not all items are instances of the given type","messagePattern":"Not all items are instances of the given type","errorType":"exception","errorClass":"JSONException","httpStatus":null,"severity":"error","filePath":"crates/tauri/mobile/android/src/main/java/app/tauri/plugin/JSArray.kt","lineNumber":26,"sourceCode":"import org.json.JSONException\n\nclass JSArray : JSONArray {\n  constructor() : super() {}\n  constructor(json: String?) : super(json) {}\n  constructor(copyFrom: Collection<*>?) : super(copyFrom) {}\n  constructor(array: Any?) : super(array) {}\n\n  @Suppress(\"UNCHECKED_CAST\", \"ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE\")\n  @Throws(JSONException::class)\n  fun <E> toList(): List<E> {\n    val items: MutableList<E> = ArrayList()\n    var o: Any? = null\n    for (i in 0 until this.length()) {\n      this.get(i).also { o = it }\n      try {\n        items.add(this.get(i) as E)\n      } catch (ex: Exception) {\n        throw JSONException(\"Not all items are instances of the given type\")\n      }\n    }\n    return items\n  }\n\n  companion object {\n    /**\n     * Create a new JSArray without throwing a error\n     */\n    fun from(array: Any?): JSArray? {\n      try {\n        return JSArray(array)\n      } catch (ex: JSONException) {\n        //\n      }\n      return null\n    }\n  }","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/tauri-apps/tauri/blob/460ec35447493200d64290dd7f015d5a91d0fd58/crates/tauri/mobile/android/src/main/java/app/tauri/plugin/JSArray.kt#L8-L44","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Inspect the plugin command signature in the Kotlin handler and send exactly that element type from JS/Rust.","Remove null/undefined entries from the array before invoking (e.g. `args.filter(a => a != null)`).","If the plugin API changed, update both the Kotlin plugin and the frontend bindings to the same version.","Catch `JSONException` on the Kotlin side (or use `opt(i)`/manual conversion) if you need tolerant parsing."],"exampleFix":"// before\ninvoke('plugin:fs|read', { paths: [null, '/a.txt'] })\n// after\ninvoke('plugin:fs|read', { paths: ['/a.txt'] }) // all elements match handler's List<String>","handlingStrategy":"type-guard","validationCode":"function assertStringArray(arr) {\n  if (!Array.isArray(arr) || arr.some(a => typeof a !== 'string'))\n    throw new TypeError('expected array of strings');\n}","typeGuard":"function isStringArray(v) {\n  return Array.isArray(v) && v.every(x => typeof x === 'string');\n}","tryCatchPattern":"// Kotlin side, tolerant parse\nval items = try { arr.toList<String>() } catch (e: JSONException) { emptyList() }","preventionTips":["Match JS argument element types to the Kotlin handler's declared types","Filter out null/undefined before invoking","Keep plugin and frontend bindings versions in sync"],"tags":["android","kotlin","json","ipc","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"460ec35447493200d64290dd7f015d5a91d0fd58","analyzedAt":"2026-09-18T23:55:51.277Z","contentChangedAt":"2026-09-18T23:55:51.277Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}