This guide helps you identify, diagnose, and resolve common issues encountered while developing, packaging, or running Chattree WebAssembly plugins.
When a plugin behaves unexpectedly, verify these items first:
plugin.json and plugin.wasm are at the root of the .chattree-plugin ZIP, not inside a subfolder.wasmSha256 in plugin.json matches the lowercase SHA-256 hash of plugin.wasm."memory": (memory (export "memory") N).entrypoint exists in your WASM module exports.plugin.json.plugin.json / plugin.wasm. (Note: Chattree's local importer automatically tolerates OS copy suffixes like plugin (1).chattree-plugin, flattens a single wrapper directory like my-plugin/plugin.json, and ignores __MACOSX or .DS_Store metadata, but strict CLI/Marketplace submission still requires root-level files.)unzip -l my-plugin.chattree-plugin on Linux/macOS or inspect the archive. You should see:
Archive: my-plugin.chattree-plugin
Length Date Time Name
--------- ---------- ----- ----
849 2026-10-14 12:00 plugin.json
1944 2026-10-14 12:00 plugin.wasm
For Marketplace submission, always package files directly at the root of the archive:
cd my-plugin && zip ../my-plugin.chattree-plugin plugin.json plugin.wasm
.chattree-plugin file with the same id..chattree-plugin file from Settings → Plugins → Importar plugin. Chattree will recognize the installed plugin ID, display the version transition (v1.0.0 → v1.1.0), and update it in place while preserving your configured settings, private storage, and SQLite database.plugin.wasm was recompiled or modified without updating wasmSha256 in plugin.json.plugin.json:
# Linux/macOS
sha256sum plugin.wasm
# Windows PowerShell
Get-FileHash plugin.wasm -Algorithm SHA256
primaryCommand or alias.primaryCommand in plugin.json to a unique identifier or uninstall the conflicting plugin."memory".(memory (export "memory") 2).#![no_main] and ensure --target wasm32-unknown-unknown is used.-Wl,--export-memory to the linker.entrypoint in plugin.json does not match any exported function name in the WASM binary.wasm-objdump -x plugin.wasm or verify spelling in entrypoint.timeoutMs (runtime default is 5000 ms, configurable up to 60,000 ms in plugin.json) or entered an infinite loop.timeoutMs up to 60000 in plugin.json if network operations require more time, or split workloads into smaller chunks.plugin.json, set "outputOffset": 32768 (or larger) and optionally "maxPayloadSizeBytes": 65536.chattree_allocate, chattree_deallocate, and chattree_dispatch to receive dynamic allocations up to 16 MB without fixed static buffer limits.permissionDenied / Permiso denegadoplugin.json → capabilities.localhost, 127.0.0.1, 192.168.x.x, or another private IP range without the network.local capability.network.local capability alongside network.http in plugin.json if your plugin integrates with local LAN/loopback services.files.read with a fabricated or expired handle.files.pick or files.write. Never hardcode handles across sessions.connection limit reached: The plugin already has 10 active connections or in-flight handshakes. Additional connection requests are blocked.close code 1009: An incoming or outgoing frame exceeded the 16 MB (16,777,216 bytes) ceiling. Chattree terminates the connection to prevent mobile memory exhaustion.websocket.close before opening new connections.UiApiHandler.sanitizeUiCard.text, badge, progress, key_value, divider, button_row).minimumIntervalViolation or Task Limit ExceededminimumIntervalViolation: The Cron schedule or interval frequency is shorter than 60 seconds.task limit reached: The plugin already has 25 active scheduled tasks.scheduler.cancel_task before registering new ones.quotaExceeded or unauthorizedStatementquotaExceeded: The plugin's SQLite database files (.db + -wal + -shm + -journal) have exceeded the 200 MB limit.unauthorizedStatement: The query attempted forbidden operations (ATTACH DATABASE, DETACH DATABASE, VACUUM INTO, or modifying sqlite_master).DELETE queries and run VACUUM to reclaim disk space.Authorization: Bearer <secret> header or a recognized webhook signature header (e.g. X-Hub-Signature-256, X-Chattree-Signature-256, X-Gitlab-Token, Stripe-Signature).path, body, and forwarded headers exceeded 3,800 bytes (MAX_DATA_BYTES). Google FCM enforces a hard 4 KB limit on the data payload envelope.http://<IP_TELEFONO>:8765), which supports full payloads up to 256 KB.FCM_TOKEN secret in Cloudflare invalid (UNREGISTERED / 404)./plugins/system/test)Authorization: Bearer <DIAGNOSTIC_SECRET_COPIADO_DE_AJUSTES> in your test request. Unauthenticated requests are rejected to prevent status bar notification flooding.fcmBackgroundHandler runs in a lightweight background isolate that does not instantiate heavy WASM runtimes or AI engines. It safely stores the event in the pending inbox (kFcmPendingInboxKey) and alerts you via a status bar notification.drainPendingInbox() immediately processes queued payloads, authenticates them, commits receipts to EventJournal, and executes the plugin handler./plugins/com.example/webhook) is not registered by any currently installed plugin, or the path is misspelled./plugins/system/test (or /plugins/test/ping).inboundWebhooks.POST requests. Sending a GET, PUT, or DELETE to /plugins/* is rejected.POST.0.0.0.0 rather than 127.0.0.1.FirebaseMessaging.onMessage triggering FlutterLocalNotificationsPlugin.show with high priority. Ensure system notification permissions are granted in Android Settings for Chattree.View live Flutter and plugin logs via Android Debug Bridge (ADB):
adb logcat -s Flutter:D | grep "\[Plugin:"
To enable verbose logging from your plugin, make core.log calls:
{
"api": "core",
"operation": "log",
"payload": {
"level": "info",
"message": "Step 1 passed"
}
}