Skip to main content

Troubleshooting Your Plugin

When a plugin misbehaves, the cause is usually one of a handful of things — and most trace back to the plugin loader's startup validation. Here are the common symptoms and where to look.

"Plugin routes return 404"​

The plugin most likely failed validation at startup, so its routes were never mounted. Check the startup logs for the plugin validation error, and confirm the manifest, table names, join-table columns, and route prefix are all correct.

"Endpoints return 403 Forbidden on what should be an authenticated request"​

The request is probably using the wrong auth type — plugin routes expect the operator JWT, not a machine API key. Confirm you're calling with an operator session, not an engine credential.

"The workflow launched, but resultHandler was never called"​

Check workflow_execution.status:

  • failed_permanent → the webhook dispatch failed, or n8n never called /complete.
  • completed but your side-effects didn't happen → your resultHandler likely threw. The core logs the exception and, because the handler runs inside the core's transaction, rolls back all your writes — and it does not retry. Check the logs for your stack trace.

"The workspace status didn't update after completion"​

Same root cause: if your resultHandler threw, the core skipped the status transition. Find the plugin's stack trace in the API logs.

"getAvailableWorkflows returns an empty list for a workspace that should have one"​

Walk the eligibility checklist: (1) the workflow is_enabled; (2) workflow.belongs_to_entity_id matches the workspace's entity; (3) workflow_eligible_status has a row for (workflow, current status); (4) the dependent configurations (workflow config, service config set) are valid. A disabled dependency anywhere in the chain removes the workflow — see the operator's dependency-chain article.

"My migrations don't run"​

Check that plugins/{entity_slug}/migrations/ is spelled exactly right and contains *.sql files. The CI and deploy loops scan by directory name — a typo in the slug means your plugin is silently skipped.

The through-line​

Notice how many of these come back to the loader and its validation: a mistyped slug, a missing join-table column, a colliding route prefix. When something's off, the startup logs are almost always the fastest answer — the loader tells you exactly which check failed. (See How the Plugin Loader Discovers & Validates Plugins for the full list of checks.)