From 251b773be716c524b41721b318f0e86439a6e469 Mon Sep 17 00:00:00 2001 From: rudaev Date: Sun, 5 Apr 2026 15:32:40 +0700 Subject: [PATCH] workaround: LINE webhook route 404 on cold start (#49803) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: when OpenClaw starts, the LINE plugin registers its webhook route (/line/webhook) but the bundler splits runtime.ts into two chunks. The chunk that initialises the global registry object first creates it without the httpRoute fields the other chunk expects — so the LINE plugin registers into one registry and the HTTP server queries a different one. Result: 404 on cold start, works after hot-reload. Upstream fix PRs #53642 and #54686 are open but both stale against the current refactored source (httpRoute structure changed completely). Workaround: a background process in entrypoint.sh waits 20s after gateway start, then writes a temporary `_reloadTs` field to openclaw.json. The gateway's file-watcher detects the change and hot-reloads the LINE channel, re-registering routes into the correct registry. The field is removed 5s later. This is explicitly documented as a workaround. Remove this block once a real fix ships from upstream and is included in the source we build from. See the extensive comment block in entrypoint.sh for full details, upstream issue links, and the two PRs tracking the real fix. Upstream issue: openclaw/openclaw#49803 Upstream PRs: openclaw/openclaw#53642, openclaw/openclaw#54686 --- scripts/entrypoint.sh | 56 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index 864eb0c..b1d3192 100644 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -302,6 +302,62 @@ nginx rm -f /tmp/openclaw-gateway.lock 2>/dev/null || true rm -f "$STATE_DIR/gateway.lock" 2>/dev/null || true +# ── LINE webhook route hot-reload workaround ───────────────────────────────── +# Bug: openclaw/openclaw#49803 — LINE (and other webhook-based channels) return +# 404 on cold start because the bundler splits runtime.ts into two chunks. The +# chunk that registers LINE routes and the chunk the HTTP server uses to look up +# routes both initialise the same global "route registry" object — but whichever +# chunk runs first creates the object without the fields the other chunk expects, +# so they end up referencing different registries. Result: routes are registered +# successfully (no error logged) but the HTTP server can't find them → 404. +# +# After a config hot-reload the channel restarts and re-registers routes into the +# correct registry, so the 404 goes away. The workaround below triggers that +# hot-reload automatically 20 seconds after the gateway starts. +# +# How it works: +# 1. Waits 20 s for the gateway to fully start and load all channel plugins. +# 2. Writes a temporary "_reloadTs" field into openclaw.json — the gateway's +# file-watcher sees the change and hot-reloads the LINE channel. +# 3. Removes the temporary field 5 s later (clean-up). +# +# This is a background process — it does NOT block gateway startup. +# Remove this block once openclaw/openclaw#49803 is fixed upstream and the +# upstream fix is merged and shipped in a release we build from. +# +# Upstream PRs tracking the real fix: +# - openclaw/openclaw#53642 (bundle-split registry mismatch fix) +# - openclaw/openclaw#54686 (syncPluginRegistry at runtime boundaries) +CONFIG_FILE="${STATE_DIR}/openclaw.json" +( + sleep 20 + if [ -f "$CONFIG_FILE" ]; then + echo "[entrypoint] applying LINE webhook route hot-reload workaround (#49803)..." + # Add a temporary field to trigger the file-watcher hot-reload + node -e " + const fs = require('fs'); + try { + const c = JSON.parse(fs.readFileSync(process.argv[1], 'utf8')); + c._reloadTs = Date.now(); + fs.writeFileSync(process.argv[1], JSON.stringify(c, null, 2)); + } catch(e) { process.exit(0); } + " "$CONFIG_FILE" + sleep 5 + # Remove the temporary field + node -e " + const fs = require('fs'); + try { + const c = JSON.parse(fs.readFileSync(process.argv[1], 'utf8')); + delete c._reloadTs; + fs.writeFileSync(process.argv[1], JSON.stringify(c, null, 2)); + } catch(e) { process.exit(0); } + " "$CONFIG_FILE" + echo "[entrypoint] LINE webhook route hot-reload complete." + else + echo "[entrypoint] WARNING: config not found at $CONFIG_FILE — skipping LINE hot-reload workaround" + fi +) & + # ── Start openclaw gateway ─────────────────────────────────────────────────── echo "[entrypoint] starting openclaw gateway on port $GATEWAY_PORT..."