Principle:Openclaw Openclaw Extension Verification
Extension Verification
Extension Verification is the principle governing how OpenClaw validates loaded extensions after discovery. For plugins, this involves discovering installed packages, loading their manifests, importing their modules, validating configuration schemas, executing registration callbacks, and recording status in a plugin registry. For skills, verification is implicit in the loading and filtering pipeline.
Overview
The extension verification phase bridges the gap between discovery (finding extension artifacts on disk) and activation (making extension capabilities available to the gateway). It ensures that:
- Every discovered plugin has a valid manifest and can be loaded.
- Plugin IDs are unique (duplicates from lower-precedence origins are disabled).
- Enable/disable state, allow/deny lists, and memory slot assignments are respected.
- Configuration schemas are validated before registration.
- Registration callbacks run successfully and register tools, hooks, channels, and other capabilities.
- Any errors are captured as diagnostics rather than crashing the gateway.
Plugin Verification Pipeline
The plugin verification pipeline is implemented by loadOpenClawPlugins() and proceeds through these stages:
Stage 1: Discovery
The discoverOpenClawPlugins() function scans four source locations in order:
| Priority | Origin | Location | Description |
|---|---|---|---|
| 1 (first scanned) | config |
Paths from plugins.load.paths |
Additional paths specified in configuration. |
| 2 | workspace |
<workspace>/.openclaw/extensions/ |
Workspace-local plugins. |
| 3 | global |
~/.openclaw/extensions/ |
User-global installed plugins. |
| 4 (last scanned) | bundled |
Built-in plugins shipped with OpenClaw | Core extension plugins. |
For each location, the function scans for:
- Single extension files (
.ts,.js,.mts, etc.) - Directories with
package.jsondeclaringopenclaw.extensions - Directories with an
index.ts/index.jsentry point
Each discovered entry becomes a PluginCandidate with an idHint, source path, rootDir, and origin.
Stage 2: Manifest Loading
The loadPluginManifestRegistry() function processes each candidate:
- Reads the
package.jsonmanifest. - Extracts plugin ID, name, description, version, kind, config schema, and UI hints.
- Records diagnostics for missing or invalid manifests.
Stage 3: Enable State Resolution
For each candidate, resolveEnableState() checks:
- Is the plugin ID on the deny list?
- Is there an allow list, and is the plugin on it?
- Is the per-plugin
entries.<id>.enabledset? - What is the plugin's origin (bundled plugins may have different default enable behavior)?
Stage 4: Deduplication
If the same plugin ID appears from multiple origins, only the first occurrence is loaded. Later occurrences are marked as disabled with the reason "overridden by <origin> plugin".
Stage 5: Module Loading
Enabled plugins are loaded via jiti (just-in-time TypeScript importer). The loader:
- Resolves
openclaw/plugin-sdkto the correct SDK path via aliasing. - Handles both
defaultexport and namedregister/activateexports. - Catches and records load errors.
Stage 6: Config Validation
If the plugin declares a config schema, the per-plugin config values are validated against it. Validation failures result in an error status and a diagnostic.
Stage 7: Registration
The plugin's register(api) function is called with an OpenClawPluginApi handle. Through this API, the plugin registers:
- Tools (agent capabilities)
- Hooks (event handlers)
- Channels (messaging integrations)
- Providers (model providers)
- Gateway methods
- HTTP handlers and routes
- CLI commands
- Services (background processes)
- Plugin commands (bypass-LLM commands)
Registration errors are caught and recorded without crashing other plugins.
Stage 8: Registry Finalization
The completed PluginRegistry contains:
- All plugin records (with status:
loaded,disabled, orerror) - All registered tools, hooks, channels, providers, gateway handlers, etc.
- A diagnostics array with warnings and errors
The registry is cached and set as the active registry for the gateway.
Skill Verification
Skills do not have a separate verification phase. Verification is implicit in the loading pipeline:
- Parse errors are silently ignored (malformed frontmatter does not prevent loading).
- Eligibility failures exclude the skill without error.
- Missing binaries or environment variables are reported via the filtering logic.
Error Handling Philosophy
The verification system follows an "errors as data" philosophy:
- No single plugin failure should crash the gateway. All errors are captured as diagnostics.
- Plugins with errors are still recorded in the registry with
status: "error"and an error message, making them visible in status commands. - Async registration is warned about but does not block (plugins should register synchronously).
Related Concepts
- Extension Type Identification -- plugins vs skills.
- Plugin Installation -- how plugins get onto disk before verification.
- Skill Loading -- how skills are discovered and filtered.
- Extension Configuration -- how configuration drives enable/disable decisions.
Implementation
Implementation:Openclaw_Openclaw_LoadOpenClawPlugins