OpenClaw Main Defines One HTTP Route Conflict Contract for Plugins
A merged plugin SDK and Gateway change canonicalizes route identity, checks every overlap and lets required webhook owners fail startup explicitly.
OpenClaw has merged a compatibility-sensitive contract change for plugin HTTP routes. Static and lifecycle registration now share one canonical collision resolver, route aliases use Gateway path identity, every overlap is inspected and required lifecycle owners can opt into fatal registration failure.
The change is on main, not proof of release inclusion. External plugin authors and operators running several webhook-backed channels should stage the containing revision before deployment.
The old ambiguity
Upstream reports that plugin routes had two partially different conflict policies. Either could stop after the first overlap, while some ownership checks compared raw path bytes even though Gateway dispatch canonicalized paths.
That mismatch allowed several bad states:
- a later hidden overlap could be missed;
- two byte-different aliases could represent one effective Gateway route;
- startup could report a route as active while handler selection depended on registration order;
- route-backed webhook or media owners could diverge from the Gateway’s identity; and
- one same-plugin route could replace a different sub-owner unintentionally.
Interpretation: routing security depends on the identity used by the dispatcher. A registry that reasons about raw strings while the Gateway reasons about canonical paths cannot prove which handler owns a request.
The new ownership contract
PR #118203 makes these rules explicit:
- static and lifecycle routes use one overlap resolver;
- every overlapping route is checked before admission;
- exact-route aliases and route-backed webhook keys use canonical Gateway identity;
- intentional nested same-auth prefix chains remain supported;
- named lifecycle replacement requires the same non-empty
pluginId; sourceis an optional stable sub-owner, and source-aware replacement requires the same non-empty source;- existing anonymous-to-anonymous refresh remains supported; and
- no general public route-sharing API is introduced.
Source-less same-plugin replacement remains compatible. Bundled source-aware callers keep stable ownership; the upstream record identifies line-webhook for LINE.
Required routes may now fail startup
The plugin SDK accepts throwOnFailure: true for lifecycle owners that cannot operate safely without their route. Default behaviour remains compatible: log the rejection and return a no-op unregister function.
Bundled Google Chat, LINE, Mattermost, SMS, Synology Chat and Zalo paths use strict failure for required bindings. The change also rolls Mattermost interactions back when later slash-command setup fails, stops LINE bot startup after strict registration failure and shares one Zalo hosted-media lease across canonical aliases.
This is the right direction for required webhooks. A channel that says “started” after failing to own its callback path is an availability lie.
What plugin authors need to decide
For every HTTP route, document:
- its canonical path identity;
- its authentication policy;
- whether nested prefix sharing is intentional;
- the stable
pluginIdthat owns replacement; - whether a distinct lifecycle sub-owner needs
source; and - whether route rejection should abort startup with
throwOnFailure.
Do not enable fatal failure indiscriminately. An optional diagnostic route can degrade safely; a required webhook generally cannot.
Acceptance test
Build a disposable Gateway with synthetic handlers:
- register raw path variants that canonicalize to the same route and prove only the authorized owner survives;
- hide a conflicting route after a benign first overlap and prove the full overlap set is inspected;
- test a permitted nested same-auth prefix chain;
- attempt replacement from another plugin and from another source within the same plugin;
- refresh a supported anonymous route;
- reject an optional route and verify the plugin degrades with a clear log;
- reject a required strict route and verify startup fails without leaving a live channel; and
- force later Mattermost-style setup failure and prove earlier route ownership rolls back.
Include encoded path forms and trailing variants accepted by the Gateway. Do not expose the fixture to the public internet.
Compatibility risk
A plugin that accidentally relied on registration order, raw-byte aliases or broad same-plugin replacement can now fail or retain a different owner. That is a deliberate safety correction, but it may reveal latent collisions during rollout.
Inventory effective routes before upgrading. Treat new conflict logs or startup failures as configuration evidence; do not suppress them or rename paths blindly until authentication and lifecycle ownership are understood.
Evidence and limits
The official merged PR, commit and documentation records establish the contract. Upstream reports 149 focused route tests plus compatibility follow-up coverage across core registry, plugin SDK, Google Chat, LINE, Mattermost, SMS, Synology Chat and Zalo. Direct GitHub extraction returned HTTP 403 and web search was unavailable.
OpenClaw Academy did not load a third-party plugin against the new SDK. Exact canonicalization rules and public types must be taken from the containing build and its generated plugin API documentation.
Collector IDs are 36431, 36291 and 36385.
Bottom line
Plugin route ownership must match the Gateway’s canonical dispatcher identity. Audit every route, assign stable owners, choose strict failure for required webhooks and stage any plugin that previously depended on registration order or path spelling.
THE RECEIPTS
Claims should survive the click.
Primary links used for this article are listed openly. If the evidence changes, the verification date changes with it.THE OPERATOR BRIEF