Troubleshooting and error codes

Applies to: StablEdge Desktop 0.4.4

Every error the host returns carries a stable code. Branch on the code in your plugin logic, and never match the human-readable message. Permission, schema, scope and input errors are not retryable; do not treat a failed grant as a temporary network problem and retry it forever.

The install fails

Work through the error codes that packaging or installing returns in this order:

  1. the manifest schema and field types;
  2. whether the entry files exist;
  3. whether files is sealed and the hashes are right;
  4. for a signed package, the publisher key id and the signature;
  5. whether the package holds duplicate entries, symbolic links or path escapes;
  6. resource limits such as package size.

Always pack again after changing anything under payload/. Do not "solve" an install problem by turning off schema, hash, signature, CSP or permission checks.

The plugin is not in the list

  • Confirm the .seplugin really installed, rather than only source having been created;
  • check the plugin's id, version and state; a newly installed plugin is disabled until you enable it;
  • check the workspace or top bar contributions in the manifest;
  • do not mistake the empty state of the plugin marketplace for the list of installed plugins.

The workspace is blank or crashes

  • Check that index.html, its scripts and its styles are all in files;
  • check whether the page does something CSP forbids: reaching the network directly, eval, inline scripts;
  • confirm that ready() is awaited before any other method is called;
  • do not throw when initialization fails; show an error panel in the interface.

No event when files are dropped

  • Check that the workspace declares drops with all three of extensions, max_files and max_bytes;
  • check that storage.blob is requested;
  • extensions are lowercase and carry no dot, and if any file in the batch is unacceptable the whole batch is refused.

The Agent claims success but nothing changes

Check one by one: whether the Agent really read the context, whether the action it used comes from available_actions, whether it really called the action, whether the host returned applied=true, whether the snapshot version went up and last_action.status is applied, and whether the interface rendered again.

If you keep getting PLUGIN_WORKSPACE_SNAPSHOT_NOT_UPDATED:

  • first check whether the action handler throws on its failure path: an exception is not passed back, so bump the version and publish a failure receipt in last_action instead;
  • check whether publish is being debounced past the roughly eight-second window for an action to take effect;
  • check whether errors from publish are being swallowed (rate limits and oversized snapshots both stop the version from growing);
  • when changes come in a burst, offer a batch action and publish once when it is done.

The worker never becomes ready

  • Is stdout carrying NDJSON protocol frames only, with no banner or debug print?
  • Does the handshake echo the request id, plugin_id and worker_id unchanged, with all five required fields present?
  • Does worker.health return ready or degraded?
  • Does stderr hold an error such as a missing dependency?
  • Are the entry file and the platform right?

The worker crashes often or is quarantined

  • Whatever follows the colon in PLUGIN_WORKER_QUARANTINED is the tail of stderr from the last exit, so fix that first;
  • a refused handshake, an invalid health check and non-JSON content on stdout each count as one exit; timeouts do not;
  • once fixed, toggle Disable → Enable or install over the plugin to reset the count with no waiting.

Every call fails after one timeout

PLUGIN_WORKER_UNRESPONSIVE usually means the worker's main thread is stuck, and has nothing to do with the handshake:

  • first check for child_process: in the sandbox it throws ERR_ACCESS_DENIED outright, so stop calling spawn, exec, fork and the like;
  • next check for large synchronous file reads and writes, unbounded loops and blocking waits on the main thread;
  • do not paper over the problem by raising timeout_ms.

Permission denied

Compare, in order, what the manifest requests, what you granted, the distribution policy and the current session. Then separate the interface-side "worker": "host" grant from a real worker's grant: the two do not carry over.

A service is missing or conflicts

  • whether the dependency is required or optional;
  • whether the API major versions are compatible;
  • whether the service has been installed and enabled on its own;
  • whether a singleton conflict exists.

Error code quick reference

Workspace Bridge error codes are in Workspace and Bridge API, and the JSON-RPC error codes a worker returns itself are in Worker.

Installation and packaging

Error codeMeaning
PLUGIN_PACKAGE_UNREADABLEThe package cannot be read: it is not a valid package, the file set is not sealed, or a Skill file does not follow the specification.
PLUGIN_PACKAGE_TOO_LARGEThe package exceeds the size limit.
PLUGIN_MANIFEST_INVALIDThe manifest breaks the schema or a cross-field rule (permission combinations, icon, word lists and so on); the message names the item.
PLUGIN_FILE_HASH_MISMATCHFile contents do not match the hashes in files, usually because a file changed and the package was not rebuilt.
PLUGIN_APP_VERSION_UNSUPPORTEDThe desktop app is older than minimum_app_version.
PLUGIN_PLATFORM_UNSUPPORTEDThe current platform is not in platforms.
PLUGIN_SIGNATURE_INVALIDThe signature check failed: the package changed after signing. Pack and sign again, or produce an unsigned package.
PLUGIN_ICON_INVALIDThe icon resource is invalid.
PLUGIN_I18N_INVALIDThe translation declarations are invalid.
PLUGIN_TYPE_INVALIDplugin_type is invalid.
PLUGIN_UNSIGNED_INSTALL_DISABLEDAllow unsigned plugins is not turned on.
PLUGIN_DEVELOPER_MODE_DISABLEDThe current build or settings do not allow this capability from a developer source.
PLUGIN_PUBLISHER_CHANGEDThe publisher changed during an upgrade.
PLUGIN_TRUSTED_WORKER_NOT_APPROVEDThe plugin contains a trusted worker that you did not confirm.
PLUGIN_PACK_FAILEDPackaging failed.
PLUGIN_INSTALL_FAILEDThe install failed.
PLUGIN_BUILTIN_NOT_REMOVABLEA bundled plugin cannot be uninstalled.

Worker (decided by the host)

The host decides the codes below and they reach the caller unchanged; error.message is CODE[:detail].

Error codeMeaning
PLUGIN_WORKER_METHOD_NOT_DECLAREDThe operation called is not in the handshake's methods, so the request never reaches the worker.
PLUGIN_WORKER_POLICY_DENIEDYou did not grant the execution policy requested (trusted or This-computer mode).
PLUGIN_WORKER_ISOLATION_POLICY_MISMATCHA worker declared as sandboxed_plugin asked for This-computer mode.
PLUGIN_WORKER_EXITEDThe worker exited before answering; the tail of stderr follows the colon.
PLUGIN_WORKER_HANDSHAKE_INVALIDThe handshake response lacks a field or the identity does not match; the field name follows the colon.
PLUGIN_WORKER_HEALTH_INVALIDThe status of the health check is neither ready nor degraded.
PLUGIN_WORKER_FRAME_TOO_LARGEA single message frame is too large and the process was ended. Pass large data with file tokens or Blob chunks.
PLUGIN_WORKER_INVALID_RESPONSEThe frame is JSON but not a valid response.
PLUGIN_WORKER_IOReading or writing the standard input and output pipe failed and the process was ended.
PLUGIN_WORKER_TIMEOUTThe call timed out but the health check that follows answered; the process is kept.
PLUGIN_WORKER_UNRESPONSIVEThe call timed out and the health check did not answer either; the process was ended.
PLUGIN_WORKER_CANCELLEDThe interface called worker.cancel.
PLUGIN_WORKER_QUARANTINEDThree exits within five minutes, so the worker is quarantined.
PLUGIN_WORKER_REMOTE_ERRORThe worker returned a JSON-RPC error, in the form PLUGIN_WORKER_REMOTE_ERROR:<code>:<message>:<data>.
PLUGIN_WORKER_FAILEDThe fallback code: what the host received was not a stable error code. Read the raw message.
PLUGIN_WORKER_FILE_TOKEN_EXPIREDThe file token has expired.
PLUGIN_WORKER_DEPENDENCY_MISSINGA service the plugin depends on is missing.
PLUGIN_SCHEDULE_TRIGGER_NOT_DECLAREDA host.schedule.* call names a trigger that the manifest does not declare.
PLUGIN_SCHEDULE_INTERVAL_INVALIDThe interval is below the declared minimum or out of range.

Network and host services

Error codeMeaning
PLUGIN_HOST_SERVICE_DENIEDservices.invoke or net.fetch was refused: the plugin is disabled, the permission is not declared with "worker": "host", or you did not grant it. Not retryable.
PLUGIN_HOST_NET_DENIEDThe URL is not http/https.
PLUGIN_HOST_NET_INVALID_REQUESTThe request parameters are invalid.
PLUGIN_HOST_NET_REQUEST_BODY_ENCODING_INVALIDBase64 encoding was declared but the body is not valid Base64.
PLUGIN_HOST_NET_REQUEST_TOO_LARGEThe request body exceeds the limit.
PLUGIN_HOST_NET_RESPONSE_TOO_LARGEThe response exceeds the limit.
PLUGIN_HOST_NET_RESPONSE_NOT_TEXTA text response was asked for but the response is not text.
PLUGIN_HOST_NET_JSON_INVALIDA JSON response was asked for but it cannot be parsed.
PLUGIN_HOST_NET_BLOB_UNAVAILABLEA blob response was asked for but there is no active workspace or no storage.blob grant.
PLUGIN_HOST_NET_FAILEDThe request failed (connection, timeout and so on).

Global services

Error codeMeaning
SERVICE_NOT_FOUNDThe service is not installed.
SERVICE_VERSION_UNSATISFIEDThe service version does not fit the dependency range.
SERVICE_SINGLETON_CONFLICTTwo instances of a singleton service conflict.
SERVICE_PERMISSION_DENIEDNo permission to call that service.
SERVICE_UNAVAILABLEThe service is temporarily unavailable.
SERVICE_DEADLINE_EXCEEDEDThe call timed out.
SERVICE_INVALID_REQUESTThe request is invalid.

Logs and privacy

Plugin logs and error messages must not contain tokens, credentials, absolute paths, full query strings, raw RPC payloads or your message text.

On this page