Environment
- OpenClaw: pre-restart version unknown; the next gateway that came up was 2026.5.4 (same install, auto-restart from update path). The shutdown SyntaxError fired on the old process being torn down.
- Backend: gateway process running under systemd-user (
openclaw-gateway.service), invoked as op run --env-file=... -- node .../openclaw/dist/index.js gateway --port 18789
- Node.js: bundled with the published npm package
- Plugins enabled: anthropic, browser, canvas, device-pair, file-transfer, memory-core, phone-control, slack, talk-voice, telegram (10 total)
- Host: single-VPS Linux deployment (hostname redacted), no container
TL;DR
During an auto-restart triggered by the openclaw update path, the outgoing gateway process fails to shut down cleanly because a dynamic import is looking up an export named 'r' from synthetic-auth.runtime.js that no longer exists. The single-letter export name strongly suggests a minified/mangled identifier — either a build-bundling collision or a stale artifact in the installed package. Co-occurs with a separate bug (see related issue below) to produce a 96-minute user-visible outage.
Symptom
A single line in the gateway journal at shutdown:
[gateway] shutdown error: SyntaxError: The requested module
'./synthetic-auth.runtime.js' does not provide an export named 'r'
Same shutdown also kills any in-flight cli-backend turn with a FailoverError:
[agent/cli-backend] claude live session turn failed:
provider=claude-cli model=claude-opus-4-7
durationMs=91970 error=FailoverError
[model-fallback/decision] model fallback decision:
decision=candidate_failed
requested=claude-cli/claude-opus-4-7
candidate=claude-cli/claude-opus-4-7
reason=unknown next=claude-cli/claude-sonnet-4-6
detail=Claude CLI failed.
The new gateway then comes up successfully and reports all plugins listening:
[gateway] http server listening (10 plugins: anthropic, browser, canvas,
device-pair, file-transfer, memory-core, phone-control, slack, talk-voice,
telegram; 6.5s)
So the SyntaxError is contained to the shutdown path of the outgoing process — the new process starts fine.
Hypothesis
'r' as an export name is almost never written by hand — it strongly suggests a mangled identifier left over from a minifier/bundler pass. Likely causes, in rough order of probability:
- Cross-bundle mangle-collision.
synthetic-auth.runtime.js is built with one minifier pass that produces export { ... as r }, and a separate consumer bundle was built with a different pass that imports 'r' by name. If the runtime bundle was rebuilt at some point without re-minifying the consumer, the names drift and the import fails.
- Stale installed artifact. The update path replaced one bundle but not its peer — the consumer is from a newer version, the runtime is from an older one (or vice versa).
- Side-effect of dynamic vs static
import(). The shutdown path may be calling import('./synthetic-auth.runtime.js') dynamically, which defers the export-name check until runtime, allowing the mismatch to ship undetected.
Repro
Not deterministically reproduced. Triggered automatically during an auto-restart along the update path. The local restart log shows the prior trigger:
[YYYY-MM-DDTHH:MM:SSZ] openclaw restart attempt source=update target=openclaw-gateway.service
[YYYY-MM-DDTHH:MM:SSZ] openclaw restart done source=update
This is the first time we've seen the SyntaxError specifically — prior restarts on this host have been clean.
Impact (in isolation)
By itself: low. The shutdown error doesn't prevent the new gateway from starting, and the only in-flight casualty is whatever turn was running at the moment of restart.
In combination with the lazy harness-registration bug filed in a peer issue (see below): high. Together they produced a 96-minute window where every inbound message hit MissingAgentHarnessError and the user got a generic "Something went wrong" reply.
Ask
- Audit the bundler/minifier config for
synthetic-auth.runtime.js and its consumers — confirm export names are either stable (not minified) or are minified consistently across all bundles in a single build.
- Consider statically importing
synthetic-auth.runtime.js so any export-name mismatch surfaces at build time, not at shutdown.
- Add a sanity check at install/update time that verifies all internal modules can resolve their declared imports (cheap: a smoke import at end of
npm postinstall).
- Independently of the fix, make the shutdown path tolerant —
shutdown error: ... should not be the only signal; a follow-up "shutdown completed (with N errors)" line would make this easier to spot in journals.
Related
- Co-occurred 2026-05-24 with a separate
MissingAgentHarnessError bug — filed as a peer issue, linked from there.
Environment
openclaw-gateway.service), invoked asop run --env-file=... -- node .../openclaw/dist/index.js gateway --port 18789TL;DR
During an auto-restart triggered by the
openclawupdate path, the outgoing gateway process fails to shut down cleanly because a dynamicimportis looking up an export named'r'fromsynthetic-auth.runtime.jsthat no longer exists. The single-letter export name strongly suggests a minified/mangled identifier — either a build-bundling collision or a stale artifact in the installed package. Co-occurs with a separate bug (see related issue below) to produce a 96-minute user-visible outage.Symptom
A single line in the gateway journal at shutdown:
Same shutdown also kills any in-flight cli-backend turn with a
FailoverError:The new gateway then comes up successfully and reports all plugins listening:
So the SyntaxError is contained to the shutdown path of the outgoing process — the new process starts fine.
Hypothesis
'r'as an export name is almost never written by hand — it strongly suggests a mangled identifier left over from a minifier/bundler pass. Likely causes, in rough order of probability:synthetic-auth.runtime.jsis built with one minifier pass that producesexport { ... as r }, and a separate consumer bundle was built with a different pass that imports'r'by name. If the runtime bundle was rebuilt at some point without re-minifying the consumer, the names drift and the import fails.import(). The shutdown path may be callingimport('./synthetic-auth.runtime.js')dynamically, which defers the export-name check until runtime, allowing the mismatch to ship undetected.Repro
Not deterministically reproduced. Triggered automatically during an auto-restart along the update path. The local restart log shows the prior trigger:
This is the first time we've seen the SyntaxError specifically — prior restarts on this host have been clean.
Impact (in isolation)
By itself: low. The shutdown error doesn't prevent the new gateway from starting, and the only in-flight casualty is whatever turn was running at the moment of restart.
In combination with the lazy harness-registration bug filed in a peer issue (see below): high. Together they produced a 96-minute window where every inbound message hit
MissingAgentHarnessErrorand the user got a generic "Something went wrong" reply.Ask
synthetic-auth.runtime.jsand its consumers — confirm export names are either stable (not minified) or are minified consistently across all bundles in a single build.synthetic-auth.runtime.jsso any export-name mismatch surfaces at build time, not at shutdown.npm postinstall).shutdown error: ...should not be the only signal; a follow-up "shutdown completed (with N errors)" line would make this easier to spot in journals.Related
MissingAgentHarnessErrorbug — filed as a peer issue, linked from there.