fix(cron): add retry policy for one-shot jobs on transient errors (#24355)#24435
Merged
Takhoffman merged 2 commits intoopenclaw:mainfrom Mar 1, 2026
Merged
fix(cron): add retry policy for one-shot jobs on transient errors (#24355)#24435Takhoffman merged 2 commits intoopenclaw:mainfrom
Takhoffman merged 2 commits intoopenclaw:mainfrom
Conversation
a688b53 to
0d526cc
Compare
Contributor
Author
|
@steipete @vincentkoc @cpojer @tyler6204 One-shot cron jobs (schedule.kind: "at") previously had no retry on transient errors (429, network, 5xx) and were permanently disabled. This PR adds transient-vs-permanent error handling and exponential backoff retries (up to 3 attempts) for one-shot jobs, with optional cron.retry config. Recurring jobs are unchanged. Backward compatible; 5 new tests, 28/28 passing. Closes #24355. Please review when you have time. |
…enclaw#24355) Co-authored-by: Cursor <cursoragent@cursor.com>
b90b1bc to
d801722
Compare
Contributor
|
PR #24435 - fix(cron): add retry policy for one-shot jobs on transient errors (#24355) (#24435) Merged via squash.
Thanks @hugenshen! |
hwb96
pushed a commit
to hwb96/openclaw
that referenced
this pull request
Mar 1, 2026
…enclaw#24355) (openclaw#24435) thanks @hugenshen Verified: - pnpm install --frozen-lockfile - pnpm check - pnpm test -- --run src/cron/service.issue-regressions.test.ts src/config/config-misc.test.ts Co-authored-by: hugenshen <16300669+hugenshen@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
zooqueen
added a commit
to hanzoai/bot
that referenced
this pull request
Mar 1, 2026
…enclaw#24355) (openclaw#24435) thanks @hugenshen Cherry-pick of upstream ea3955c.
vincentkoc
added a commit
that referenced
this pull request
Mar 2, 2026
vincentkoc
added a commit
that referenced
this pull request
Mar 2, 2026
* changelog: credit @BUGKillerKing for #29315 * changelog: credit @liuweifly for #14674 * changelog: credit @Sid-Qin for #29709 * changelog: credit @lailoo for #21808 * changelog: credit @openperf for #26259 * changelog: credit @icesword0760 for #28959 * changelog: credit @cowboy129 for #28529 * changelog: credit @yfge for #17798 * changelog: credit @kcinzgg for #27325 * changelog: credit @guoqunabc for #28494 * changelog: credit @WilsonLiu95 for #12755 * changelog: credit @qiangu for #18529 * changelog: credit @lailoo for unreleased #27616 * changelog: credit @tumf for unreleased #18642 * changelog: normalize unreleased #24789 credit handle * changelog: fill unreleased #24435 credit * changelog: fill unreleased #25090 credit * changelog: fill unreleased #29098 credit (entry 1) * changelog: fill unreleased #29098 credit (entry 2) * changelog: credit @liuxiaopai-ai for unreleased #30567 * changelog: credit @graysurf for unreleased #23169 * changelog: credit @pablohrcarvalho for unreleased #10686 * changelog: credit @Glucksberg for unreleased #21715 * changelog: credit @liuxiaopai-ai for unreleased #30586 * changelog: add missing credits for 2026.2.26 * changelog: add missing credits for 2026.2.25 * changelog: add missing credits for 2026.2.24 * changelog: add missing credits for 2026.2.23 * changelog: add missing credits for 2026.2.22
ansh
pushed a commit
to vibecode/openclaw
that referenced
this pull request
Mar 2, 2026
…enclaw#24355) (openclaw#24435) thanks @hugenshen Verified: - pnpm install --frozen-lockfile - pnpm check - pnpm test -- --run src/cron/service.issue-regressions.test.ts src/config/config-misc.test.ts Co-authored-by: hugenshen <16300669+hugenshen@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
ansh
pushed a commit
to vibecode/openclaw
that referenced
this pull request
Mar 2, 2026
…aw#31079) * changelog: credit @BUGKillerKing for openclaw#29315 * changelog: credit @liuweifly for openclaw#14674 * changelog: credit @Sid-Qin for openclaw#29709 * changelog: credit @lailoo for openclaw#21808 * changelog: credit @openperf for openclaw#26259 * changelog: credit @icesword0760 for openclaw#28959 * changelog: credit @cowboy129 for openclaw#28529 * changelog: credit @yfge for openclaw#17798 * changelog: credit @kcinzgg for openclaw#27325 * changelog: credit @guoqunabc for openclaw#28494 * changelog: credit @WilsonLiu95 for openclaw#12755 * changelog: credit @qiangu for openclaw#18529 * changelog: credit @lailoo for unreleased openclaw#27616 * changelog: credit @tumf for unreleased openclaw#18642 * changelog: normalize unreleased openclaw#24789 credit handle * changelog: fill unreleased openclaw#24435 credit * changelog: fill unreleased openclaw#25090 credit * changelog: fill unreleased openclaw#29098 credit (entry 1) * changelog: fill unreleased openclaw#29098 credit (entry 2) * changelog: credit @liuxiaopai-ai for unreleased openclaw#30567 * changelog: credit @graysurf for unreleased openclaw#23169 * changelog: credit @pablohrcarvalho for unreleased openclaw#10686 * changelog: credit @Glucksberg for unreleased openclaw#21715 * changelog: credit @liuxiaopai-ai for unreleased openclaw#30586 * changelog: add missing credits for 2026.2.26 * changelog: add missing credits for 2026.2.25 * changelog: add missing credits for 2026.2.24 * changelog: add missing credits for 2026.2.23 * changelog: add missing credits for 2026.2.22
steipete
pushed a commit
to Sid-Qin/openclaw
that referenced
this pull request
Mar 2, 2026
…enclaw#24355) (openclaw#24435) thanks @hugenshen Verified: - pnpm install --frozen-lockfile - pnpm check - pnpm test -- --run src/cron/service.issue-regressions.test.ts src/config/config-misc.test.ts Co-authored-by: hugenshen <16300669+hugenshen@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
steipete
pushed a commit
to Sid-Qin/openclaw
that referenced
this pull request
Mar 2, 2026
…aw#31079) * changelog: credit @BUGKillerKing for openclaw#29315 * changelog: credit @liuweifly for openclaw#14674 * changelog: credit @Sid-Qin for openclaw#29709 * changelog: credit @lailoo for openclaw#21808 * changelog: credit @openperf for openclaw#26259 * changelog: credit @icesword0760 for openclaw#28959 * changelog: credit @cowboy129 for openclaw#28529 * changelog: credit @yfge for openclaw#17798 * changelog: credit @kcinzgg for openclaw#27325 * changelog: credit @guoqunabc for openclaw#28494 * changelog: credit @WilsonLiu95 for openclaw#12755 * changelog: credit @qiangu for openclaw#18529 * changelog: credit @lailoo for unreleased openclaw#27616 * changelog: credit @tumf for unreleased openclaw#18642 * changelog: normalize unreleased openclaw#24789 credit handle * changelog: fill unreleased openclaw#24435 credit * changelog: fill unreleased openclaw#25090 credit * changelog: fill unreleased openclaw#29098 credit (entry 1) * changelog: fill unreleased openclaw#29098 credit (entry 2) * changelog: credit @liuxiaopai-ai for unreleased openclaw#30567 * changelog: credit @graysurf for unreleased openclaw#23169 * changelog: credit @pablohrcarvalho for unreleased openclaw#10686 * changelog: credit @Glucksberg for unreleased openclaw#21715 * changelog: credit @liuxiaopai-ai for unreleased openclaw#30586 * changelog: add missing credits for 2026.2.26 * changelog: add missing credits for 2026.2.25 * changelog: add missing credits for 2026.2.24 * changelog: add missing credits for 2026.2.23 * changelog: add missing credits for 2026.2.22
safzanpirani
pushed a commit
to safzanpirani/clawdbot
that referenced
this pull request
Mar 2, 2026
…enclaw#24355) (openclaw#24435) thanks @hugenshen Verified: - pnpm install --frozen-lockfile - pnpm check - pnpm test -- --run src/cron/service.issue-regressions.test.ts src/config/config-misc.test.ts Co-authored-by: hugenshen <16300669+hugenshen@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
safzanpirani
pushed a commit
to safzanpirani/clawdbot
that referenced
this pull request
Mar 2, 2026
…aw#31079) * changelog: credit @BUGKillerKing for openclaw#29315 * changelog: credit @liuweifly for openclaw#14674 * changelog: credit @Sid-Qin for openclaw#29709 * changelog: credit @lailoo for openclaw#21808 * changelog: credit @openperf for openclaw#26259 * changelog: credit @icesword0760 for openclaw#28959 * changelog: credit @cowboy129 for openclaw#28529 * changelog: credit @yfge for openclaw#17798 * changelog: credit @kcinzgg for openclaw#27325 * changelog: credit @guoqunabc for openclaw#28494 * changelog: credit @WilsonLiu95 for openclaw#12755 * changelog: credit @qiangu for openclaw#18529 * changelog: credit @lailoo for unreleased openclaw#27616 * changelog: credit @tumf for unreleased openclaw#18642 * changelog: normalize unreleased openclaw#24789 credit handle * changelog: fill unreleased openclaw#24435 credit * changelog: fill unreleased openclaw#25090 credit * changelog: fill unreleased openclaw#29098 credit (entry 1) * changelog: fill unreleased openclaw#29098 credit (entry 2) * changelog: credit @liuxiaopai-ai for unreleased openclaw#30567 * changelog: credit @graysurf for unreleased openclaw#23169 * changelog: credit @pablohrcarvalho for unreleased openclaw#10686 * changelog: credit @Glucksberg for unreleased openclaw#21715 * changelog: credit @liuxiaopai-ai for unreleased openclaw#30586 * changelog: add missing credits for 2026.2.26 * changelog: add missing credits for 2026.2.25 * changelog: add missing credits for 2026.2.24 * changelog: add missing credits for 2026.2.23 * changelog: add missing credits for 2026.2.22
steipete
pushed a commit
to Sid-Qin/openclaw
that referenced
this pull request
Mar 2, 2026
…enclaw#24355) (openclaw#24435) thanks @hugenshen Verified: - pnpm install --frozen-lockfile - pnpm check - pnpm test -- --run src/cron/service.issue-regressions.test.ts src/config/config-misc.test.ts Co-authored-by: hugenshen <16300669+hugenshen@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
steipete
pushed a commit
to Sid-Qin/openclaw
that referenced
this pull request
Mar 2, 2026
…aw#31079) * changelog: credit @BUGKillerKing for openclaw#29315 * changelog: credit @liuweifly for openclaw#14674 * changelog: credit @Sid-Qin for openclaw#29709 * changelog: credit @lailoo for openclaw#21808 * changelog: credit @openperf for openclaw#26259 * changelog: credit @icesword0760 for openclaw#28959 * changelog: credit @cowboy129 for openclaw#28529 * changelog: credit @yfge for openclaw#17798 * changelog: credit @kcinzgg for openclaw#27325 * changelog: credit @guoqunabc for openclaw#28494 * changelog: credit @WilsonLiu95 for openclaw#12755 * changelog: credit @qiangu for openclaw#18529 * changelog: credit @lailoo for unreleased openclaw#27616 * changelog: credit @tumf for unreleased openclaw#18642 * changelog: normalize unreleased openclaw#24789 credit handle * changelog: fill unreleased openclaw#24435 credit * changelog: fill unreleased openclaw#25090 credit * changelog: fill unreleased openclaw#29098 credit (entry 1) * changelog: fill unreleased openclaw#29098 credit (entry 2) * changelog: credit @liuxiaopai-ai for unreleased openclaw#30567 * changelog: credit @graysurf for unreleased openclaw#23169 * changelog: credit @pablohrcarvalho for unreleased openclaw#10686 * changelog: credit @Glucksberg for unreleased openclaw#21715 * changelog: credit @liuxiaopai-ai for unreleased openclaw#30586 * changelog: add missing credits for 2026.2.26 * changelog: add missing credits for 2026.2.25 * changelog: add missing credits for 2026.2.24 * changelog: add missing credits for 2026.2.23 * changelog: add missing credits for 2026.2.22
robertchang-ga
pushed a commit
to robertchang-ga/openclaw
that referenced
this pull request
Mar 2, 2026
…enclaw#24355) (openclaw#24435) thanks @hugenshen Verified: - pnpm install --frozen-lockfile - pnpm check - pnpm test -- --run src/cron/service.issue-regressions.test.ts src/config/config-misc.test.ts Co-authored-by: hugenshen <16300669+hugenshen@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
robertchang-ga
pushed a commit
to robertchang-ga/openclaw
that referenced
this pull request
Mar 2, 2026
…aw#31079) * changelog: credit @BUGKillerKing for openclaw#29315 * changelog: credit @liuweifly for openclaw#14674 * changelog: credit @Sid-Qin for openclaw#29709 * changelog: credit @lailoo for openclaw#21808 * changelog: credit @openperf for openclaw#26259 * changelog: credit @icesword0760 for openclaw#28959 * changelog: credit @cowboy129 for openclaw#28529 * changelog: credit @yfge for openclaw#17798 * changelog: credit @kcinzgg for openclaw#27325 * changelog: credit @guoqunabc for openclaw#28494 * changelog: credit @WilsonLiu95 for openclaw#12755 * changelog: credit @qiangu for openclaw#18529 * changelog: credit @lailoo for unreleased openclaw#27616 * changelog: credit @tumf for unreleased openclaw#18642 * changelog: normalize unreleased openclaw#24789 credit handle * changelog: fill unreleased openclaw#24435 credit * changelog: fill unreleased openclaw#25090 credit * changelog: fill unreleased openclaw#29098 credit (entry 1) * changelog: fill unreleased openclaw#29098 credit (entry 2) * changelog: credit @liuxiaopai-ai for unreleased openclaw#30567 * changelog: credit @graysurf for unreleased openclaw#23169 * changelog: credit @pablohrcarvalho for unreleased openclaw#10686 * changelog: credit @Glucksberg for unreleased openclaw#21715 * changelog: credit @liuxiaopai-ai for unreleased openclaw#30586 * changelog: add missing credits for 2026.2.26 * changelog: add missing credits for 2026.2.25 * changelog: add missing credits for 2026.2.24 * changelog: add missing credits for 2026.2.23 * changelog: add missing credits for 2026.2.22
hanqizheng
pushed a commit
to hanqizheng/openclaw
that referenced
this pull request
Mar 2, 2026
…enclaw#24355) (openclaw#24435) thanks @hugenshen Verified: - pnpm install --frozen-lockfile - pnpm check - pnpm test -- --run src/cron/service.issue-regressions.test.ts src/config/config-misc.test.ts Co-authored-by: hugenshen <16300669+hugenshen@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
hanqizheng
pushed a commit
to hanqizheng/openclaw
that referenced
this pull request
Mar 2, 2026
…aw#31079) * changelog: credit @BUGKillerKing for openclaw#29315 * changelog: credit @liuweifly for openclaw#14674 * changelog: credit @Sid-Qin for openclaw#29709 * changelog: credit @lailoo for openclaw#21808 * changelog: credit @openperf for openclaw#26259 * changelog: credit @icesword0760 for openclaw#28959 * changelog: credit @cowboy129 for openclaw#28529 * changelog: credit @yfge for openclaw#17798 * changelog: credit @kcinzgg for openclaw#27325 * changelog: credit @guoqunabc for openclaw#28494 * changelog: credit @WilsonLiu95 for openclaw#12755 * changelog: credit @qiangu for openclaw#18529 * changelog: credit @lailoo for unreleased openclaw#27616 * changelog: credit @tumf for unreleased openclaw#18642 * changelog: normalize unreleased openclaw#24789 credit handle * changelog: fill unreleased openclaw#24435 credit * changelog: fill unreleased openclaw#25090 credit * changelog: fill unreleased openclaw#29098 credit (entry 1) * changelog: fill unreleased openclaw#29098 credit (entry 2) * changelog: credit @liuxiaopai-ai for unreleased openclaw#30567 * changelog: credit @graysurf for unreleased openclaw#23169 * changelog: credit @pablohrcarvalho for unreleased openclaw#10686 * changelog: credit @Glucksberg for unreleased openclaw#21715 * changelog: credit @liuxiaopai-ai for unreleased openclaw#30586 * changelog: add missing credits for 2026.2.26 * changelog: add missing credits for 2026.2.25 * changelog: add missing credits for 2026.2.24 * changelog: add missing credits for 2026.2.23 * changelog: add missing credits for 2026.2.22
execute008
pushed a commit
to execute008/openclaw
that referenced
this pull request
Mar 2, 2026
…enclaw#24355) (openclaw#24435) thanks @hugenshen Verified: - pnpm install --frozen-lockfile - pnpm check - pnpm test -- --run src/cron/service.issue-regressions.test.ts src/config/config-misc.test.ts Co-authored-by: hugenshen <16300669+hugenshen@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
execute008
pushed a commit
to execute008/openclaw
that referenced
this pull request
Mar 2, 2026
…aw#31079) * changelog: credit @BUGKillerKing for openclaw#29315 * changelog: credit @liuweifly for openclaw#14674 * changelog: credit @Sid-Qin for openclaw#29709 * changelog: credit @lailoo for openclaw#21808 * changelog: credit @openperf for openclaw#26259 * changelog: credit @icesword0760 for openclaw#28959 * changelog: credit @cowboy129 for openclaw#28529 * changelog: credit @yfge for openclaw#17798 * changelog: credit @kcinzgg for openclaw#27325 * changelog: credit @guoqunabc for openclaw#28494 * changelog: credit @WilsonLiu95 for openclaw#12755 * changelog: credit @qiangu for openclaw#18529 * changelog: credit @lailoo for unreleased openclaw#27616 * changelog: credit @tumf for unreleased openclaw#18642 * changelog: normalize unreleased openclaw#24789 credit handle * changelog: fill unreleased openclaw#24435 credit * changelog: fill unreleased openclaw#25090 credit * changelog: fill unreleased openclaw#29098 credit (entry 1) * changelog: fill unreleased openclaw#29098 credit (entry 2) * changelog: credit @liuxiaopai-ai for unreleased openclaw#30567 * changelog: credit @graysurf for unreleased openclaw#23169 * changelog: credit @pablohrcarvalho for unreleased openclaw#10686 * changelog: credit @Glucksberg for unreleased openclaw#21715 * changelog: credit @liuxiaopai-ai for unreleased openclaw#30586 * changelog: add missing credits for 2026.2.26 * changelog: add missing credits for 2026.2.25 * changelog: add missing credits for 2026.2.24 * changelog: add missing credits for 2026.2.23 * changelog: add missing credits for 2026.2.22
hughdidit
pushed a commit
to hughdidit/DAISy-Agency
that referenced
this pull request
Mar 3, 2026
…aw#31079) * changelog: credit @BUGKillerKing for openclaw#29315 * changelog: credit @liuweifly for openclaw#14674 * changelog: credit @Sid-Qin for openclaw#29709 * changelog: credit @lailoo for openclaw#21808 * changelog: credit @openperf for openclaw#26259 * changelog: credit @icesword0760 for openclaw#28959 * changelog: credit @cowboy129 for openclaw#28529 * changelog: credit @yfge for openclaw#17798 * changelog: credit @kcinzgg for openclaw#27325 * changelog: credit @guoqunabc for openclaw#28494 * changelog: credit @WilsonLiu95 for openclaw#12755 * changelog: credit @qiangu for openclaw#18529 * changelog: credit @lailoo for unreleased openclaw#27616 * changelog: credit @tumf for unreleased openclaw#18642 * changelog: normalize unreleased openclaw#24789 credit handle * changelog: fill unreleased openclaw#24435 credit * changelog: fill unreleased openclaw#25090 credit * changelog: fill unreleased openclaw#29098 credit (entry 1) * changelog: fill unreleased openclaw#29098 credit (entry 2) * changelog: credit @liuxiaopai-ai for unreleased openclaw#30567 * changelog: credit @graysurf for unreleased openclaw#23169 * changelog: credit @pablohrcarvalho for unreleased openclaw#10686 * changelog: credit @Glucksberg for unreleased openclaw#21715 * changelog: credit @liuxiaopai-ai for unreleased openclaw#30586 * changelog: add missing credits for 2026.2.26 * changelog: add missing credits for 2026.2.25 * changelog: add missing credits for 2026.2.24 * changelog: add missing credits for 2026.2.23 * changelog: add missing credits for 2026.2.22 (cherry picked from commit ee96e17) # Conflicts: # CHANGELOG.md
dorgonman
pushed a commit
to kanohorizonia/openclaw
that referenced
this pull request
Mar 3, 2026
…enclaw#24355) (openclaw#24435) thanks @hugenshen Verified: - pnpm install --frozen-lockfile - pnpm check - pnpm test -- --run src/cron/service.issue-regressions.test.ts src/config/config-misc.test.ts Co-authored-by: hugenshen <16300669+hugenshen@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
dorgonman
pushed a commit
to kanohorizonia/openclaw
that referenced
this pull request
Mar 3, 2026
…aw#31079) * changelog: credit @BUGKillerKing for openclaw#29315 * changelog: credit @liuweifly for openclaw#14674 * changelog: credit @Sid-Qin for openclaw#29709 * changelog: credit @lailoo for openclaw#21808 * changelog: credit @openperf for openclaw#26259 * changelog: credit @icesword0760 for openclaw#28959 * changelog: credit @cowboy129 for openclaw#28529 * changelog: credit @yfge for openclaw#17798 * changelog: credit @kcinzgg for openclaw#27325 * changelog: credit @guoqunabc for openclaw#28494 * changelog: credit @WilsonLiu95 for openclaw#12755 * changelog: credit @qiangu for openclaw#18529 * changelog: credit @lailoo for unreleased openclaw#27616 * changelog: credit @tumf for unreleased openclaw#18642 * changelog: normalize unreleased openclaw#24789 credit handle * changelog: fill unreleased openclaw#24435 credit * changelog: fill unreleased openclaw#25090 credit * changelog: fill unreleased openclaw#29098 credit (entry 1) * changelog: fill unreleased openclaw#29098 credit (entry 2) * changelog: credit @liuxiaopai-ai for unreleased openclaw#30567 * changelog: credit @graysurf for unreleased openclaw#23169 * changelog: credit @pablohrcarvalho for unreleased openclaw#10686 * changelog: credit @Glucksberg for unreleased openclaw#21715 * changelog: credit @liuxiaopai-ai for unreleased openclaw#30586 * changelog: add missing credits for 2026.2.26 * changelog: add missing credits for 2026.2.25 * changelog: add missing credits for 2026.2.24 * changelog: add missing credits for 2026.2.23 * changelog: add missing credits for 2026.2.22
hughdidit
added a commit
to hughdidit/DAISy-Agency
that referenced
this pull request
Mar 5, 2026
* CLI: add root --help fast path and lazy channel option resolution (#30975)
* CLI argv: add strict root help invocation guard
* Entry: add root help fast-path bootstrap bypass
* CLI context: lazily resolve channel options
* CLI context tests: cover lazy channel option resolution
* CLI argv tests: cover root help invocation detection
* Changelog: note additional startup path optimizations
* Changelog: split startup follow-up into #30975 entry
* CLI channel options: load precomputed startup metadata
* CLI channel options tests: cover precomputed metadata path
* Build: generate CLI startup metadata during build
* Build script: invoke CLI startup metadata generator
* CLI routes: preload plugins for routed health
* CLI routes tests: assert health plugin preload
* CLI: add experimental bundled entry and snapshot helper
* Tools: compare CLI startup entries in benchmark script
* Docs: add startup tuning notes for Pi and VM hosts
* CLI: drop bundled entry runtime toggle
* Build: remove bundled and snapshot scripts
* Tools: remove bundled-entry benchmark shortcut
* Docs: remove bundled startup bench examples
* Docs: remove Pi bundled entry mention
* Docs: remove VM bundled entry mention
* Changelog: remove bundled startup follow-up claims
* Build: remove snapshot helper script
* Build: remove CLI bundle tsdown config
* Doctor: add low-power startup optimization hints
* Doctor: run startup optimization hint checks
* Doctor tests: cover startup optimization host targeting
* Doctor tests: mock startup optimization note export
* CLI argv: require strict root-only help fast path
* CLI argv tests: cover mixed root-help invocations
* CLI channel options: merge metadata with runtime catalog
* CLI channel options tests: assert dynamic catalog merge
* Changelog: align #30975 startup follow-up scope
* Docs tests: remove secondary-entry startup bench note
* Docs Pi: add systemd recovery reference link
* Docs VPS: add systemd recovery reference link
* feat(agents): make openai responses websocket-first with fallback
* chore(changelog): note openai websocket-first streaming
* docs(security): clarify local link-priming reports as out-of-scope
* docs: clarify Anthropic context1m long-context requirements
* doctor: warn on macOS cloud-synced state directories (#31004)
* Doctor: detect macOS cloud-synced state directories
* Doctor tests: cover cloud-synced macOS state detection
* Docs: note cloud-synced state warning in doctor guide
* Docs: recommend local macOS state dir placement
* Changelog: add macOS cloud-synced state dir warning
* Changelog: credit macOS cloud state warning PR
* Doctor state: anchor cloud-sync roots to macOS home
* Doctor tests: cover OPENCLAW_HOME cloud-sync override
* Doctor state: prefer resolved target for cloud detection
* Doctor tests: cover local-target cloud symlink case
* test(agents): port OpenAI websocket coverage from #24911
Co-authored-by: Jonathan Jing <achillesjing@gmail.com>
* fix(security): harden sandbox novnc observer flow
* test: fix fetch mock typing casts
* feat(openai): add websocket warm-up with configurable toggle
* test(config): reject discord open DM with empty allowFrom
* Docs: add all unlisted docs routes to navigation (#31027)
* Docs: add missing platform pages to nav
* Docs: include all unlisted docs routes in nav
* Docs nav: classify routes by area and remove catch-all groups
* Docs nav: remove ja-JP AGENTS page entry
* Docs ja-JP: remove AGENTS translation workspace page
* Docs nav: remove refactor plans group
* Docs nav: remove .dev template pages
* Docs nav: remove operations hubs group
* fix(agents): type openai websocket warmup passthrough
* feat(agents): use structured internal completion events
* fix(channels): align command-body parsing sources
* fix(security): harden inbound metadata sentinel stripping
* chore(changelog): note internal events and ingress hardening
* fix(browser): harden writable output paths
* docs(acp): add permission configuration section and troubleshooting entries
Document permissionMode and nonInteractivePermissions plugin config
keys for the acpx backend. Add troubleshooting entries for:
- Permission prompt errors in non-interactive ACP sessions
- Silent session failures from swallowed permission errors
- Stalled ACP sessions that never report completion
Relates to #29195
AI-assisted (lightly tested)
* fix: align ACP permission docs defaults (#31044) (thanks @barronlroth)
* fix(security): harden clawlog command execution
* fix(macos): harden exec approvals socket path and permissions
* fix(agents): land #20840 cross-channel message-tool actions from @altaywtf
Include scoped cross-channel action/description behavior, regression tests, changelog note, and make Ollama discovery tests URL-scoped to avoid env-dependent fetch interference.
Co-authored-by: Altay <altay@hey.com>
* fix(acpx): harden windows cmd wrapper spawning
* fix(docker): harden /app/extensions permissions to 755 (#30191)
* fix(docker): harden /app/extensions permissions to 755
Bundled extension directories shipped as world-writable (mode 777)
in the Docker image. The plugin security scanner blocks any world-
writable path with:
WARN: blocked plugin candidate: world-writable path
(/app/extensions/memory-core, mode=777)
Add chmod -R 755 /app/extensions in the final USER root RUN step so
all bundled extensions are readable but not world-writable. This runs
as root before switching back to the node user, matching the pattern
already used for chmod 755 /app/openclaw.mjs.
Fixes #30139
* fix(docker): normalize plugin and agent path permissions
* docs(changelog): add docker permissions entry for #30191
* Update CHANGELOG.md
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(skills): validate installer metadata specs
* fix(skills): constrain plugin skill paths
* docs(changelog): note skills security hardening
* fix(discord): harden reconnect recovery and preserve message delivery
Landed from contributor PR #29508 by @cgdusek.
Co-authored-by: Charles Dusek <cgdusek@gmail.com>
* fix(plugins): prioritize bundled duplicates in auto-discovery
Landed from contributor PR #29710 by @Sid-Qin.
Co-authored-by: SidQin-cyber <sidqin0410@gmail.com>
* fix(discord): unify dm command auth gating
* fix(agents): harden tool-name normalization and transcript repair
Landed from contributor PRs #30620 and #30735 by @Sid-Qin, plus #30881 by @liuxiaopai-ai.
Co-authored-by: SidQin-cyber <sidqin0410@gmail.com>
Co-authored-by: liuxiaopai-ai <73659136+liuxiaopai-ai@users.noreply.github.com>
* test(discord): stabilize model picker timeout assertions
* fix(acpx): share windows wrapper resolver and add strict hardening mode
* refactor(discord): unify DM command auth handling
* test(discord): cover DM command decision flow
* docs(changelog): add missing contributor credits for 2026.3.1 (#31079)
* changelog: credit @BUGKillerKing for #29315
* changelog: credit @liuweifly for #14674
* changelog: credit @Sid-Qin for #29709
* changelog: credit @lailoo for #21808
* changelog: credit @openperf for #26259
* changelog: credit @icesword0760 for #28959
* changelog: credit @cowboy129 for #28529
* changelog: credit @yfge for #17798
* changelog: credit @kcinzgg for #27325
* changelog: credit @guoqunabc for #28494
* changelog: credit @WilsonLiu95 for #12755
* changelog: credit @qiangu for #18529
* changelog: credit @lailoo for unreleased #27616
* changelog: credit @tumf for unreleased #18642
* changelog: normalize unreleased #24789 credit handle
* changelog: fill unreleased #24435 credit
* changelog: fill unreleased #25090 credit
* changelog: fill unreleased #29098 credit (entry 1)
* changelog: fill unreleased #29098 credit (entry 2)
* changelog: credit @liuxiaopai-ai for unreleased #30567
* changelog: credit @graysurf for unreleased #23169
* changelog: credit @pablohrcarvalho for unreleased #10686
* changelog: credit @Glucksberg for unreleased #21715
* changelog: credit @liuxiaopai-ai for unreleased #30586
* changelog: add missing credits for 2026.2.26
* changelog: add missing credits for 2026.2.25
* changelog: add missing credits for 2026.2.24
* changelog: add missing credits for 2026.2.23
* changelog: add missing credits for 2026.2.22
* fix(session): harden usage accounting and memory flush recovery
* feat(diagnostics): add configurable stuck-session warning threshold
* docs(changelog): record session lifecycle and diagnostics fixes
* fix(gateway): land access/auth/config migration cluster
Land #28960 by @Glucksberg (Tailscale origin auto-allowlist).
Land #29394 by @synchronic1 (allowedOrigins upgrade migration).
Land #29198 by @Mariana-Codebase (plugin HTTP auth guard + route precedence).
Land #30910 by @liuxiaopai-ai (tailscale bind/config.patch guard).
Co-authored-by: Glucksberg <markuscontasul@gmail.com>
Co-authored-by: synchronic1 <synchronic1@users.noreply.github.com>
Co-authored-by: Mariana Sinisterra <mariana.data@outlook.com>
Co-authored-by: liuxiaopai-ai <73659136+liuxiaopai-ai@users.noreply.github.com>
* test(lobster): preserve execFile in child_process mock
* fix(security): harden webhook memory guards across channels
* fix(matrix): fix multiple Conduit compatibility issues preventing message delivery
## Changes
### 1. Fix client.start() hanging forever (shared.ts)
The bot-sdk's `client.start()` returns a promise that never resolves
(infinite sync loop). The plugin awaited it, blocking the entire provider
startup — `logged in as` never printed, no messages were processed.
Fix: fire-and-forget with error handler + 2s initialization delay.
### 2. Fix DM false positive for 2-member rooms (direct.ts)
`memberCount === 2` heuristic misclassified explicitly configured group
rooms as DMs when only bot + one user were joined. Messages were routed
through DM policy and silently dropped.
Fix: remove member count heuristic; only trust `m.direct` account data
and `is_direct` room state flag.
Ref: #20145
### 3. Prevent duplicate event listener registration (events.ts)
When both bundled channel plugin and extension load, listeners were
registered twice on the same shared client, causing inconsistent state.
Fix: WeakSet guard to skip registration if client already has listeners.
Ref: #18330
### 4. Add startup grace period (index.ts)
`startupGraceMs = 0` dropped messages timestamped during async setup.
Especially problematic with Conduit which retries on `M_NOT_FOUND`
during filter creation.
Fix: 5-second grace period.
### 5. Fix room ID case sensitivity with Conduit (index.ts)
Room IDs (`!xyz`) without `:server` suffix failed the
`includes(':')` check and were sent to `resolveMatrixTargets`, which
called Conduit's `resolveRoom` — returning lowercased IDs. The bot-sdk
emits events with original-case IDs, causing config lookup mismatches
and reply delivery failures (`M_UNKNOWN: non-create event for room of
unknown version`).
Fix: treat `!`-prefixed entries as room IDs directly (skip resolution).
Only resolve `#alias:server` entries.
## Testing
Tested with Conduit homeserver (lightweight Rust Matrix server).
All fixes verified with gateway log tracing:
- `logged in as @arvi:matrix.local` — first successful login
- `room.message` events fire and reach handler
- Room config matching returns `allowed: true`
- Agent generates response and delivers it to Matrix room
* fix: address review feedback — handle start failure, remove placeholder URL
- Don't mark client as started if client.start() errors during init
- Remove placeholder issue URL from comment
* fix: propagate client.start() errors to caller instead of swallowing
Codex review feedback: ensureSharedClientStarted now throws the error
from client.start() if it rejects during the 2s grace window, so
resolveSharedMatrixClient() properly reports failure (e.g. bad token,
unreachable homeserver) instead of leaving the provider in a
running-but-not-syncing state.
* fix: handle late client.start() failures via single catch handler
The .catch() handler now covers both early and late failures:
- Within 2s: sets settled=true, startup throws to caller
- After 2s: sets params.state.started=false so subsequent
resolveSharedMatrixClient() calls detect the dead client
Removed redundant second .catch() — single handler covers all cases.
* fix: harden matrix startup errors + add regressions (#31023) (thanks @efe-arv)
* fix(gateway): harden node metadata policy classification
* fix(discord): unify reconnect watchdog and land #31025/#30530
Landed follow-up intent from contributor PR #31025 (@theotarr) and PR #30530 (@liuxiaopai-ai).
Co-authored-by: theotarr <theotarr@users.noreply.github.com>
Co-authored-by: liuxiaopai-ai <liuxiaopai-ai@users.noreply.github.com>
* refactor(gateway): unify metadata canonicalization + platform rules
* fix(gateway): enforce owner boundary for agent runs
* refactor(security): unify webhook guardrails across channels
* refactor(session): consolidate transcript snapshot reads
* refactor(config): share byte-size parsing for memory flush
* refactor(diagnostics): hot-reload stuck warning threshold
* fix(session): retire stale dm main route after dmScope migration (#31010)
* Doctor: warn when Linux state dir is on SD/eMMC mounts (#31033)
* Doctor state: warn on Linux SD or eMMC state mounts
* Doctor tests: cover Linux SD or eMMC state mount detection
* Docs doctor: document Linux SD or eMMC state warning
* Changelog: add Linux SD or eMMC doctor warning
* Update CHANGELOG.md
* Doctor: escape mountinfo control chars in SD warning
* Doctor tests: cover escaped mountinfo control chars
* refactor(matrix): unify startup + split monitor config flow
* Fixes minor security vulnerability (#30948) (#30951)
Merged via squash.
Prepared head SHA: cfbe5fe8301370d751b3c62d908533f00d583933
Co-authored-by: benediktjohannes <253604130+benediktjohannes@users.noreply.github.com>
Co-authored-by: shakkernerd <165377636+shakkernerd@users.noreply.github.com>
Reviewed-by: @shakkernerd
* refactor(gateway): dedupe origin seeding and plugin route auth matching
* Tests: type Discord gateway lifecycle wait mock
* test(discord): type gateway stop mock params
* fix(protocol): regenerate swift gateway models for internalEvents
* chore(format): swiftformat host env and exec approvals (#31115)
* fix(tools): land #31015 from @haosenwang1018
Co-authored-by: haosenwang1018 <1293965075@qq.com>
* fix(slack): land #31028 from @taw0002
Co-authored-by: taw0002 <webmaster@sodsolutions.com>
* fix: harden sandbox media reads against TOCTOU escapes
* docs(changelog): credit GHSA-6f6j reporter
* fix(security): block private-network web_search citation redirects
* fix(agents): land #31007 from @HOYALIM
Co-authored-by: Ho Lim <subhoya@gmail.com>
* fix(agents): land #31002 from @yfge
Co-authored-by: yfge <geyunfei@gmail.com>
* test(discord): type gateway stop mock params
* fix: handle CLI session expired errors gracefully instead of crashing gateway (#31090)
* fix: handle CLI session expired errors gracefully
- Add session_expired to FailoverReason type
- Add isCliSessionExpiredErrorMessage to detect expired CLI sessions
- Modify runCliAgent to retry with new session when session expires
- Update agentCommand to clear expired session IDs from session store
- Add proper error handling to prevent gateway crashes on expired sessions
Fixes #30986
* fix: add session_expired to AuthProfileFailureReason and missing log import
* fix: type cli-runner usage field to match EmbeddedPiAgentMeta
* fix: harden CLI session-expiry recovery handling
* build: regenerate host env security policy swift
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix: deliver subagent completion announces to Slack without invalid thread_ts (#31105)
* fix(subagent): avoid invalid Slack thread_ts for bound completion announces
* build: regenerate host env security policy swift
---------
Co-authored-by: User <user@example.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(security): enforce sandbox inheritance for sessions_spawn
* fix(signal): prevent sentTranscript sync messages from bypassing loop protection (#31093)
* fix(signal): prevent sentTranscript sync messages from bypassing loop protection
Issue: #31084
On daemon restart, sentTranscript sync messages could bypass loop protection
because the syncMessage check happened before the sender validation. This
reorganizes the checks to:
1. First resolve the sender (phone or UUID)
2. Check if the message is from our own account (both phone and UUID)
3. Only skip sync messages from other sources after confirming not own account
This ensures that sync messages from the own account are properly filtered
to prevent self-reply loops, while still allowing messages synced from other
devices to be processed.
Added optional accountUuid config field for UUID-based account identification.
* fix(signal): cover UUID-only own-message loop protection
* build: regenerate host env security policy swift
---------
Co-authored-by: Kevin Wang <kevin@example.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(gateway): support wildcard in controlUi.allowedOrigins for remote access (#31088)
* fix(gateway): support wildcard in controlUi.allowedOrigins for remote access
* build: regenerate host env security policy swift
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* refactor!: remove versioned system-run approval contract
* CLI: avoid plugin preload for health --json route (#31108)
* CLI routes: skip plugin preload for health --json
* CLI routes tests: cover health --json plugin preload
* refactor(web): split trusted and strict web tool fetch paths
* fix(auto-reply): land #31080 from @scoootscooob
Co-authored-by: scoootscooob <zhentongfan@gmail.com>
* feat(agents): add sessions_spawn sandbox require mode
* fix(security): harden root-scoped writes against symlink races
* fix: allow docker cli container to connect to gateway (#12504)
* Docker: route CLI through gateway network namespace
* Tests: assert Docker Compose CLI namespace wiring
* Changelog: add Docker Compose CLI connectivity fix
* Docker: pin docker setup gateway mode and bind
* Tests: cover docker setup mode and bind sync
* Docs: clarify Docker LAN vs loopback gateway targeting
* Changelog: expand Docker #12504 targeting note
* Docker: default optional CLAUDE compose vars to empty
* Docs(Docker): document non-interactive compose runs
* Changelog: note docker compose env-noise reduction
* Docker: restore onboarding Tailscale guidance
* Docker: simplify onboarding output and clarify Tailscale
* Docker: harden shared-namespace CLI container
* Docs(Docker): document shared-namespace trust boundary
* Changelog: note docker shared-namespace hardening
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* docs(changelog): add entries for PRs #31090 #31105 #31093 #31088
* docs(security): document sessions_spawn sandbox=require hardening
* fix(acpx): default strict windows wrapper policy on windows
* test(browser): fix windows download tmp path assertions
* Cron: fix 1/3 timeout on fresh isolated CLI runs (openclaw#30140) thanks @ningding97
Verified:
- pnpm build
- pnpm check
- pnpm test:macmini
Co-authored-by: ningding97 <17723822+ningding97@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* Node install: persist gateway token in service env (#31122)
* Node daemon: persist gateway token env
* changelog: add credits for node gateway token fix
* changelog: credit byungsker for node token service fix
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(fs): honor unset tools.fs.workspaceOnly default (land #31128 by @SaucePackets)
Landed-from: #31128
Contributor: @SaucePackets
Co-authored-by: SaucePackets <33006469+SaucePackets@users.noreply.github.com>
* test(cron): add Asia/Shanghai year-regression coverage [AI-assisted] (openclaw#30565) thanks @liuxiaopai-ai
Verified:
- pnpm build
- pnpm check
- pnpm test:macmini
Co-authored-by: liuxiaopai-ai <73659136+liuxiaopai-ai@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* fix(routing): treat group/channel peer.kind as equivalent (land #31135 by @Sid-Qin)
Landed-from: #31135
Contributor: @Sid-Qin
Co-authored-by: Sid <sidqin0410@gmail.com>
* fix(doctor): use posix path semantics for linux sd detection
* fix(telegram): skip nullish final text sends (land #30969 by @haosenwang1018)
Landed-from: #30969
Contributor: @haosenwang1018
Co-authored-by: Sense_wang <167664334+haosenwang1018@users.noreply.github.com>
* fix(cron): recover flat patch params for update action and fix schema (openclaw#23221) thanks @charojo
Verified:
- pnpm build
- pnpm check
- pnpm test:macmini
Co-authored-by: charojo <4084797+charojo@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* fix(nodes): cap screen_record duration to 5 minutes (land #31106 by @BlueBirdBack)
Landed-from: #31106
Contributor: @BlueBirdBack
Co-authored-by: BlueBirdBack <126304167+BlueBirdBack@users.noreply.github.com>
* fix(cron): reject sessionTarget "main" for non-default agents at creation time (openclaw#30217) thanks @liaosvcaf
Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check
- pnpm test:macmini
Co-authored-by: liaosvcaf <51533973+liaosvcaf@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* Control UI/Cron: persist delivery mode none on edit (openclaw#31114) thanks @liuxiaopai-ai
Verified:
- pnpm build
- pnpm check
- pnpm test:macmini
Co-authored-by: liuxiaopai-ai <73659136+liuxiaopai-ai@users.noreply.github.com>
Co-authored-by: Takhoffman <781889+Takhoffman@users.noreply.github.com>
* fix(cli): set cron run exit code from run outcome (land #31121 by @Sid-Qin)
Landed-from: #31121
Contributor: @Sid-Qin
Co-authored-by: Sid <sidqin0410@gmail.com>
* fix(cron): prevent armTimer tight loop when job has stuck runningAtMs (openclaw#29853) thanks @FlamesCN
Verified:
- pnpm build
- pnpm check
- pnpm test:macmini
Co-authored-by: FlamesCN <12966659+FlamesCN@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* fix(cron): retry rename on EBUSY and fall back to copyFile on Windows
Landed from contributor PR #16932 with additional changelog alignment and verification.
* fix(discord): log ignored messages from non-allowlisted channels
Closes #30676
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(discord): add ackReactionScope channel override + off/none values (#28268)
* fix(discord): support applied_tags parameter for forum thread creation
Forum channels that require tags fail with "A tag is required" when
creating threads because there was no way to pass tag IDs. Add
appliedTags parameter to the thread-create action so forum posts can
include required tags from the channel's available_tags list.
* fix(discord): add token-based fallback for application ID resolution
When the Discord API call to /oauth2/applications/@me fails (timeout,
network error), the bot fails to start with "Failed to resolve Discord
application id". Add a fallback that extracts the application ID by
base64-decoding the first segment of the bot token, keeping it as a
string to avoid precision loss for snowflake IDs exceeding
Number.MAX_SAFE_INTEGER (2^53 - 1).
Fixes #29608
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test(discord): add unit tests for parseApplicationIdFromToken
Cover valid tokens, large snowflake IDs exceeding MAX_SAFE_INTEGER,
Bot-prefixed tokens, and various invalid/edge-case inputs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(discord): restrict token fallback to transport/timeout errors only
Address review feedback: only fall back to token-based ID extraction
on transport/timeout errors (catch block), not on HTTP auth failures
(401/403) which should fail fast to surface credential issues early.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* discord: expose EventQueue listenerTimeout as configurable option (fixes #24458)
* fix(docker): ensure agent directory permissions in docker-setup.sh (#28841)
* fix(docker): ensure agent directory permissions in docker-setup.sh
* fix(docker): restrict chown to config-dir mount, not workspace
The previous 'chown -R node:node /home/node/.openclaw' call crossed into
the workspace bind mount on Linux hosts, recursively rewriting ownership
of all user project files in the workspace directory.
Fix: use 'find -xdev' to restrict chown to the config-dir filesystem
only (won't cross bind-mount boundaries). Then separately chown only
the OpenClaw metadata subdirectory (.openclaw/) within the workspace,
leaving the user's project files untouched.
Addresses review comment on PR #28841.
* fix(telegram): handle sendVoice caption-too-long by resending without caption
When TTS text exceeds Telegram's 1024-char caption limit, sendVoice
throws "message caption is too long" and the entire reply (voice +
text) is lost. Now catch this specific error, resend the voice note
without caption, then deliver the full text as a separate message.
Closes #30980
Made-with: Cursor
* fix(telegram): check chat allowlist before sender allowlist in group policy
When groupPolicy is "allowlist", the sender allowlist empty-entries
guard ran before the chat-level allowlist check. This caused groups
that were explicitly configured in the groups config to be silently
rejected when no allowFrom / groupAllowFrom entries existed.
Move the checkChatAllowlist block before the sender allowlist guard
and introduce a chatExplicitlyAllowed flag that distinguishes a
dedicated group entry (groupConfig is set) from a wildcard-only
match. When the chat is explicitly allowed and no sender entries
exist, skip the sender check entirely — the group ID itself acts
as the authorization.
Fixes #30613.
* fix(telegram): prevent channel-level groups from leaking to all accounts in multi-account setups
In multi-account Telegram configurations, `mergeTelegramAccountConfig()`
performs a shallow merge of channel-level config onto each account. This
causes channel-level `groups` to be inherited by ALL accounts, including
those whose bots are not members of the configured groups.
When a secondary bot attempts to handle group messages for a group it is
not in, the failure disrupts message delivery for all accounts — causing
silent message loss with no errors in logs.
Fix: exclude `groups` from the base spread (like `accounts` already is)
and only apply channel-level groups as fallback in single-account setups
for backward compatibility. Multi-account setups must use account-level
groups config.
Added 5 test cases covering single-account inheritance, multi-account
isolation, account-level priority, and backward compatibility.
Fixes #30673
* fix(agents): trigger model failover on connection-refused and network-unreachable errors
Previously, only ETIMEDOUT / ESOCKETTIMEDOUT / ECONNRESET / ECONNABORTED
were recognised as failover-worthy network errors. Connection-level
failures such as ECONNREFUSED (server down), ENETUNREACH / EHOSTUNREACH
(network disconnected), ENETRESET, and EAI_AGAIN (DNS failure) were
treated as unknown errors and did not advance the fallback chain.
This is particularly impactful when a local fallback model (e.g. Ollama)
is configured: if the remote provider is unreachable due to a network
outage, the gateway should fall back to the local model instead of
returning an error to the user.
Add the missing error codes to resolveFailoverReasonFromError() and
corresponding e2e tests.
Closes #18868
* test: add missing ENETRESET test case
* fix: add changelog for #19077 (thanks @ayanesakura)
* fix: refresh Copilot token before expiry and retry on auth errors
GitHub Copilot API tokens expire after ~30 minutes. When OpenClaw spawns
a long-running subagent using Copilot as the provider, the token would
expire mid-session with no recovery mechanism, causing 401 auth errors.
This commit adds:
- Periodic token refresh scheduled 5 minutes before expiry
- Auth error detection with automatic token refresh and single retry
- Proper timer cleanup on session shutdown to prevent leaks
The implementation uses a per-attempt retry flag to ensure each auth
error can trigger one refresh+retry cycle without creating infinite
retry loops.
🤖 AI-assisted: This fix was developed with GitHub Copilot CLI assistance.
Testing: Fully tested with 3 new unit tests covering auth retry, retry
reset, and timer cleanup scenarios. All 11 auth rotation tests pass.
* fix: add changelog for #8805 (thanks @Arthur742Ramos)
* Telegram: preserve proxy-aware global dispatcher
* Telegram: stop bot on polling teardown
* docs(changelog): add entries for recent landed Discord PRs
* feat: lightweight bootstrap context mode for heartbeat/cron runs (openclaw#26064) thanks @jose-velez
Verified:
- pnpm build
- pnpm check (fails on pre-existing unrelated repo issues in extensions/diffs and src/agents/tools/nodes-tool.test.ts)
- pnpm vitest run src/agents/bootstrap-files.test.ts src/infra/heartbeat-runner.model-override.test.ts src/cli/cron-cli.test.ts
- pnpm test:macmini (fails on pre-existing extensions/diffs import errors; touched suites pass)
Co-authored-by: jose-velez <10926182+jose-velez@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* docs: backfill telegram changelog credits for merged PRs
* docs(discord): standardize eventQueue timeout guidance
* fix(security): warn on wildcard control-ui origins and feishu owner grants
* fix(slack): scope download-file to channel and thread context
* docs(changelog): note security audit and slack download scope hardening
* fix(windows): land #31147 plugin install spawn EINVAL (@codertony)
Landed from contributor PR #31147 by @codertony.
Co-authored-by: codertony <codertony@users.noreply.github.com>
* fix(line): land #31151 M4A voice MIME detection (@scoootscooob)
Landed from contributor PR #31151 by @scoootscooob.
Co-authored-by: scoootscooob <scoootscooob@users.noreply.github.com>
* fix(cron): land #31145 explicit delivery none in editor (@byungsker)
Landed from contributor PR #31145 by @byungsker.
Co-authored-by: byungsker <byungsker@users.noreply.github.com>
* Docs(Docker): clarify official GHCR image usage and setup flow (#31180)
* Add pre built images to docker docs
* Docs(Docker): clarify official GHCR image guidance
* Changelog: document Docker docs image clarification
* Update CHANGELOG.md
---------
Co-authored-by: Ken <ken@ipl31.net>
* fix(ui): land #30978 debug event log full-width payloads (@stozo04)
Landed from contributor PR #30978 by @stozo04.
Co-authored-by: stozo04 <stozo04@users.noreply.github.com>
* fix(ui): land #31133 cron edit form viewport scrolling (@Sid-Qin)
Landed from contributor PR #31133 by @Sid-Qin.
Co-authored-by: Sid-Qin <Sid-Qin@users.noreply.github.com>
* fix: harden sessions_spawn delivery params and telegram account routing (#31000, #31110)
* docs(changelog): add diffs entry
* fix(ollama): prioritize provider baseUrl for embedded runner (#30964)
* fix(ollama): honor provider baseUrl in embedded runner
* Embedded Ollama: clarify provider baseUrl precedence comment
* Changelog: note embedded Ollama baseUrl precedence fix
* Telegram: apply required formatter update in accounts config merge
* Revert "Telegram: apply required formatter update in accounts config merge"
This reverts commit d372b26975ce1ab8245f6f7c2aa242f58dfc6a6d.
* Update CHANGELOG.md
---------
Co-authored-by: User <user@example.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* security(feishu): bind doc create grants to trusted requester context (#31184)
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* fix(telegram): scope DM topic thread keys by chat id (#31064)
* fix(telegram): scope DM topic thread keys by chat id
* test(telegram): update dm topic session-key expectation
* fix(telegram): parse scoped dm thread ids in outbound recovery
* chore(telegram): format accounts config merge block
* test(nodes): simplify mocked exports for ts tuple spreads
* fix(telegram): replyToMode 'first' now only applies reply-to to first chunk
The `replyToMessageIdForPayload` was computed once outside the chunk
and media loops, so all chunks received the same reply-to ID even when
replyToMode was set to "first". This replaces the static binding with
a lazy `resolveReplyTo()` function that checks `hasReplied` at each
send site, and updates `hasReplied` immediately after the first
successful send.
Fixes #31039
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: cover voice fallback first-chunk reply behavior (#31077)
* fix(telegram): retry DM thread sends without message_thread_id [AI-assisted]
* fix(telegram): skip null/undefined final text payloads
* docs: credit telegram empty-final regression coverage (#30746)
* telegram: retry media fetch with IPv4 fallback on connect errors (#30554)
* telegram: retry fetch once with IPv4 fallback on connect errors
* test(telegram): format fetch fallback test
* style(telegram): apply oxfmt for fetch test
* fix(telegram): retry ipv4 fallback per request
* test: harden telegram ipv4 fallback coverage (#30554)
---------
Co-authored-by: root <root@vultr.guest>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* docs: add missing changelog entry for #31064
* fix(model): land #30932 auth-profile @ parsing for /model (@haosenwang1018)
Landed from contributor PR #30932 by @haosenwang1018.
Co-authored-by: haosenwang1018 <haosenwang1018@users.noreply.github.com>
* fix(discord): keep attachment metadata when media fetch is blocked
Preserve inbound attachment/sticker metadata in Discord message context when media download fails (for example due to SSRF blocking), so agents still see file references instead of silent drops.
Closes #28816
* fix: harden discord media fallback regressions (#28906) (thanks @Sid-Qin)
* fix(discord): accept cid in agent component interactions
* fix(discord): guard cid decode to avoid URIError
* style: oxfmt for agent-components
* fix: harden discord agent cid parsing (#29013) (thanks @Jacky1n7)
* fix(discord): prevent wildcard component registration collisions
Assign distinct sentinel registration ids to Discord wildcard handlers while preserving wildcard parser keys, so select/menu/modal handlers no longer get dropped on runtimes that dedupe by raw customId.
* fix: normalize Discord wildcard sentinel parsing (#29459) (thanks @Sid-Qin)
* fix(matrix): land #31201 preserve room ID casing (@williamos-dev)
Landed from contributor PR #31201 by @williamos-dev.
Co-authored-by: williamos-dev <williamos-dev@users.noreply.github.com>
* refactor: simplify telegram delivery and outbound session resolver flow
* fix(cli): keep json preflight stdout machine-readable
* test(cli): avoid brittle mock call indexing in json-mode checks
* fix(cli): preserve json stdout while keeping doctor migration (#24368) (thanks @altaywtf)
* fix(models): land #31202 normalize custom provider keys (@stakeswky)
Landed from contributor PR #31202 by @stakeswky.
Co-authored-by: stakeswky <stakeswky@users.noreply.github.com>
* fix(mattermost): land #30891 route private channels as group (@BlueBirdBack)
Landed from contributor PR #30891 by @BlueBirdBack.
Co-authored-by: BlueBirdBack <BlueBirdBack@users.noreply.github.com>
* fix(googlechat): land #30965 thread reply option support (@novan)
Landed from contributor PR #30965 by @novan.
Co-authored-by: novan <novan@users.noreply.github.com>
* fix(feishu): harden routing, parsing, and media delivery
* Docker: add OCI base-image labels and document base-image metadata (#31196)
* Docker: add OCI base image labels
* Docs(Docker): document base image metadata context
* Changelog: note Docker base annotation docs update
* Changelog: add author credit for Docker base annotations
* Update docker.md
* Docker: add OCI source and docs labels
* CI(Docker): publish OCI revision/version labels
* Docs(Docker): list OCI image annotations
* Changelog: expand OCI annotation coverage note
* Docker: set OCI license annotation to MIT
* Docs(Docker): align OCI license annotation to MIT
* Docker: note docs sync path for OCI annotations
* Docker: normalize OCI label block indentation
* fix(auto-reply): normalize block-reply callback to Promise for timeout path (#31200)
* Auto-reply: wrap block reply callback in Promise.resolve for timeout safety
* Build: add strict smoke build script for CI regression gating
* CI: gate strict TS smoke build in check workflow
* docs(changelog): add auto-reply block reply timeout fix under Unreleased
* docs(changelog): credit original #19779 contributor and vincentkoc
* docs(changelog): credit feishu fix contributors
* fix(signal): land #31138 syncMessage presence filtering (@Sid-Qin)
Landed from contributor PR #31138 by @Sid-Qin.
Co-authored-by: Sid-Qin <sidqin0410@gmail.com>
* fix(origin-check): honour "*" wildcard in gateway.controlUi.allowedOrigins
When gateway.controlUi.allowedOrigins is set to ["*"], the Control UI
WebSocket was still rejected with "origin not allowed" for any non-
loopback origin (e.g. Tailscale IPs, LAN addresses).
Root cause: checkBrowserOrigin() compared each allowedOrigins entry
against the parsed request origin via a literal Array#includes(). The
entry "*" never equals an actual origin string, so the wildcard was
silently ignored and all remote connections were blocked.
Fix: check for the literal "*" entry before the per-origin comparison
and return ok:true immediately when found.
Closes #30990
* fix(cron): re-arm one-shot at-jobs when rescheduled after completion (openclaw#28915) thanks @Glucksberg
Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check
- pnpm test:macmini
Co-authored-by: Glucksberg <80581902+Glucksberg@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* fix(usage): clamp negative input token counts to zero
Some OpenAI-format providers (via pi-ai) pre-subtract cached_tokens from
prompt_tokens upstream. When cached_tokens exceeds prompt_tokens due to
provider inconsistencies the subtraction produces a negative input value
that flows through to the TUI status bar and /usage dashboard.
Clamp rawInput to 0 in normalizeUsage() so downstream consumers never
see nonsensical negative token counts.
Closes #30765
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test(usage): cover negative prompt_tokens alias clamp
* fix(session): preserve external lastTo routing for internal turns
* test(session): cover internal route without external fallback
* fix(feishu): land #31209 prevent system preview leakage (@stakeswky)
Landed from contributor PR #31209 by @stakeswky.
Co-authored-by: stakeswky <stakeswky@users.noreply.github.com>
* docs(changelog): merge post-v2026.2.26 release notes
* fix(secrets): normalize inline SecretRef token/key to tokenRef/keyRef in runtime snapshot (#31047)
* fix(secrets): normalize inline SecretRef token/key to tokenRef/keyRef in runtime snapshot
When auth-profiles.json uses an inline SecretRef as the token or key
value directly (e.g. `"token": {"source":"file",...}`), the resolved
plaintext was written back to disk on every updateAuthProfileStoreWithLock
call, overwriting the SecretRef.
Root cause: collectTokenProfileAssignment and collectApiKeyProfileAssignment
detected inline SecretRefs but did not promote them to the canonical
tokenRef/keyRef fields. saveAuthProfileStore only strips plaintext when
tokenRef/keyRef is set, so the inline case fell through and persisted
plaintext on every save.
Fix: when an inline SecretRef is detected and no explicit tokenRef/keyRef
exists, promote it to the canonical field and delete the inline form.
saveAuthProfileStore then correctly strips the resolved plaintext on write.
Fixes #29108
* fix test: cast inline SecretRef loadAuthStore mocks to AuthProfileStore
* fix(secrets): fix TypeScript type error in runtime test loadAuthStore lambda
* test(secrets): keep explicit keyRef precedence over inline key ref
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(infra): avoid EISDIR leak to messaging when Read targets directory (Closes #31186)
* test(fs-safe): assert directory-read errors never leak EISDIR text
* docs(changelog): credit fixes from PRs #31058 #31211 #30941 #31047 #31205
* feat(telegram): improve DM topics support (#30579) (thanks @kesor)
* fix(inbound-meta): land #30984 include account_id context (@Stxle2)
Landed from contributor PR #30984 by @Stxle2.
Co-authored-by: Stxle2 <166609401+Stxle2@users.noreply.github.com>
* Diffs: add viewer payload validation and presentation defaults
* Gateway: harden control-ui vs plugin HTTP precedence
* Fix onboard ignoring OPENCLAW_GATEWAY_TOKEN env var (#22658)
* Fix onboard ignoring OPENCLAW_GATEWAY_TOKEN env var
When running onboard via docker-setup.sh, the QuickStart wizard
generates its own 48-char token instead of using the 64-char token
already set in OPENCLAW_GATEWAY_TOKEN. This causes a token mismatch
that breaks all CLI commands after setup.
Check process.env.OPENCLAW_GATEWAY_TOKEN before falling back to
randomToken() in both the interactive QuickStart path and the
non-interactive path.
Closes #22638
Co-authored-by: Clawborn <tianrun.yang103@gmail.com>
* Tests: cover quickstart env token fallback
* Changelog: note docker onboarding token parity fix
* Tests: restore env var after non-interactive token fallback test
* Update CHANGELOG.md
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(feishu): harden target routing, dedupe, and reply fallback
* fix(web-tools): land #31176 allow RFC2544 trusted fetch range (@sunkinux)
Landed from contributor PR #31176 by @sunkinux.
Co-authored-by: sunkinux <sunkinux@users.noreply.github.com>
* fix(agents): unblock gpt-5.3-codex API-key routing and replay (#31083)
* fix(agents): unblock gpt-5.3-codex API-key replay path
* fix(agents): scope OpenAI replay ID rewrites per turn
* test: fix nodes-tool mock typing and reformat telegram accounts
* docs(gateway): document Docker bridge networking and loopback bind caveat (#28001)
* docs(gateway): document Docker bridge networking and loopback bind caveat
The default loopback bind makes the gateway unreachable with Docker
bridge networking because port-forwarded traffic arrives on eth0, not
lo. Add a note in both the Dockerfile and the configuration reference
explaining the workarounds (--network host or bind: lan).
Fixes #27950
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(docker): note legacy gateway.bind alias migration
* docs(gateway): clarify legacy bind alias auto-migration
* docs(docker): require bind mode values in gateway.bind
* docs(gateway): avoid bind alias auto-migration claim
* changelog: add #28001 docker bind docs credit
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(telegram): land #31067 first-chunk voice-fallback reply refs (@xdanger)
Landed from contributor PR #31067 by @xdanger.
Co-authored-by: Kros Dai <xdanger@gmail.com>
* feat(agents): support `thinkingDefault: "adaptive"` for Anthropic models (#31227)
* feat(agents): support `thinkingDefault: "adaptive"` for Anthropic models
Anthropic's Opus 4.6 and Sonnet 4.6 support adaptive thinking where the
model dynamically decides when and how much to think. This is now
Anthropic's recommended mode and `budget_tokens` is deprecated on these
models.
Add "adaptive" as a valid thinking level:
- Config: `agents.defaults.thinkingDefault: "adaptive"`
- CLI: `/think adaptive` or `/think auto`
- Pi SDK mapping: "adaptive" → "medium" effort at the pi-agent-core
layer, which the Anthropic provider translates to
`thinking.type: "adaptive"` with `output_config.effort: "medium"`
- Provider fallbacks: OpenRouter and Google map "adaptive" to their
respective "medium" equivalents
Closes #30880
Made-with: Cursor
* style(changelog): format changelog with oxfmt
* test(types): fix strict typing in runtime/plugin-context tests
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(config): normalize gateway bind host aliases during migration (#30855)
* fix(config): normalize gateway bind host aliases during migration [AI-assisted]
* config(legacy): detect gateway.bind host aliases as legacy
* config(legacy): sanitize bind alias migration log output
* test(config): cover bind alias legacy detection and log escaping
* config(legacy): add source-literal gate to legacy rules
* config(legacy): make issue detection source-aware
* config(legacy): require source-literal gateway.bind alias detection
* config(io): pass parsed source to legacy issue detection
* test(config): cover resolved-only gateway.bind alias legacy detection
* changelog: format after #30855 rebase conflict resolution
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(feishu): skip typing indicator on old messages after context compaction (#30418)
* fix(feishu): suppress stale replay typing indicators (#30709) (thanks @arkyu2077)
* Feishu: serialize startup bot-info probes
* Feishu: skip duplicate bot-info retries after preflight
* fix: harden feishu startup probe sequencing (#29941) (thanks @bmendonca3)
* fix(agents): prioritize per-model thinking defaults (#30439)
* fix(agents): honor per-model thinking defaults
* fix(agents): preserve thinking fallback with model defaults
---------
Co-authored-by: Mark L <73659136+markliuyuxiang@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(gateway): raise health-monitor restart cap
* fix(channels): add optional defaultAccount routing
* test(mattermost): cover defaultAccount resolution
* refactor: centralize delivery/path/media/version lifecycle
* refactor(feishu): split monitor startup and transport concerns
* fix: isolate docker onboard e2e config env
* refactor: split telegram delivery and unify media/frontmatter/i18n pipelines
* style(swift): apply swiftformat and swiftlint fixes
* chore: fix gate formatting and raw-fetch allowlist lines
* fix(discord): enrich allowlist resolution logs
* docs: reorder unreleased changelog by user impact
* chore(deps): bump workspace dependencies
* fix(cron): guard against year-rollback in croner nextRun (#30777)
* fix(cron): guard against year-rollback in croner nextRun
Croner can return a past-year timestamp for some timezone/date
combinations (e.g. Asia/Shanghai). When nextRun returns a value at or
before nowMs, retry from the next whole second and, if still stale,
from midnight-tomorrow UTC before giving up.
Closes #30351
* googlechat: guard API calls with SSRF-safe fetch
* test: fix hoisted plugin context mock setup
---------
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* fix(thinking): default Claude 4.6 to adaptive
* fix(android): align lint gates and photo permission handling
* fix(ci): resolve i18n typing and generated-policy drift
* style(changelog): apply oxfmt
* Exec/ACP: inject OPENCLAW_SHELL into child shell env (#31271)
* exec: mark runtime shell context in exec env
* tests(exec): cover OPENCLAW_SHELL in gateway exec
* tests(exec): cover OPENCLAW_SHELL in pty mode
* acpx: mark runtime shell context for spawned process
* tests(acpx): log OPENCLAW_SHELL in runtime fixture
* tests(acpx): assert OPENCLAW_SHELL in runtime prompt
* docs(env): document OPENCLAW_SHELL runtime markers
* docs(exec): describe OPENCLAW_SHELL exec marker
* docs(acp): document OPENCLAW_SHELL acp marker
* docs(gateway): note OPENCLAW_SHELL for background exec
* tui: tag local shell runs with OPENCLAW_SHELL
* tests(tui): assert OPENCLAW_SHELL in local shell runner
* acp client: tag spawned bridge env with OPENCLAW_SHELL
* tests(acp): cover acp client OPENCLAW_SHELL env helper
* docs(env): include acp-client and tui-local shell markers
* docs(acp): document acp-client OPENCLAW_SHELL marker
* docs(tui): document tui-local OPENCLAW_SHELL marker
* exec: keep shell runtime env string-only for docker args
* changelog: note OPENCLAW_SHELL runtime markers
* fix(discord): prefer names in allowlist resolution logs
* fix(ci): drop redundant env assertions in daemon status
* CLI: add config path subcommand to print active config file path (#26256)
Merged via squash.
Prepared head SHA: b11c593a34c5730f4244c054e1d1ab536953b0ef
Co-authored-by: cyb1278588254 <48212932+cyb1278588254@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
* fix: resolve i18n merge conflict and test hoist failure
* fix(ios): enforce main-actor device status APIs
* fix(ios): eliminate voice wake and xcode build warnings
* Gateway: add healthz/readyz probe endpoints for container checks (#31272)
* Gateway: add HTTP liveness/readiness probe routes
* Gateway tests: cover probe route auth bypass and methods
* Docker Compose: add gateway /healthz healthcheck
* Docs: document Docker probe endpoints
* Dockerfile: note built-in probe endpoints
* Gateway: make probe routes fallback-only to avoid shadowing
* Gateway tests: verify probe paths do not shadow plugin routes
* Changelog: note gateway container probe endpoints
* build: prepare 2026.3.1-beta.1 release
* docs: update appcast for 2026.3.1
* upgrade: rebase onto upstream v2026.3.1
Start from upstream release v2026.3.1 and re-apply DAISy-Agency
customizations: CI/CD workflows, GCP deployment infrastructure,
MongoDB memory extension, security hardening, platform fixes.
Changes applied onto upstream base:
- CI/CD: branch filters (daisy/main, daisy/dev), workflow_dispatch,
iOS conditional, docker tag strategy for dev builds
- Security: default client scope operator.read, exec approval default
always, sandbox tool allowlist reduced to read-only
- Platform: vitest Windows workers/timeout/parallelism tuning,
browser profile clawd->daisy compat normalization
- Tests: sequential annotation on flaky parallel tests
- New: 9 custom workflows, deployment scripts, GCP infra scripts,
mongodb memory extension, documentation, security reviews
Replaces cherry-pick approach (PRs #144-#148) which failed due
to pervasive naming divergence across 7,500+ upstream commits.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add permissions blocks and branch filters per code review
- Add `permissions: {contents: read}` to ci.yml, workflow-sanity.yml,
and sandbox-common-smoke.yml (addresses 11 CodeQL findings)
- Fix sandbox-common-smoke.yml branch filter: main → daisy/main + daisy/dev
(Copilot review comment)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address Codex P2 review findings
- session-utils.fs: count archive removals only after deletion
succeeds, preventing false cleanup counts when files are locked
- usage: format startDate/endDate respecting the requested
utcOffset/mode instead of always using UTC calendar fields
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: prevent code injection in detect-docs-changes action
Pass github event context through env vars instead of direct ${{ }}
interpolation in shell script to prevent code injection (CodeQL
alerts #255-#257).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: replace Blacksmith CI runners with GitHub-hosted runners
We don't have Blacksmith runners. Replace all references:
- blacksmith-16vcpu-ubuntu-2404 → ubuntu-latest
- blacksmith-16vcpu-ubuntu-2404-arm → ubuntu-latest + QEMU
- blacksmith-16vcpu-windows-2025 → windows-latest
Add docker/setup-qemu-action for arm64 Docker builds on x86
runners. Remove Blacksmith labels and ignore patterns from
actionlint config.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: resolve actionlint failures in patchbot and deploy workflows
Remove invalid `branches` filter from pull_request_review and
check_suite events in patchbot.yml (not supported per GitHub spec,
router job already handles branch filtering).
Suppress environment-scoped secret warnings in deploy.yml only
(staging secrets are invisible to actionlint static analysis).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: repair ci.yml YAML syntax and remove invalid toLower in claude-pr-review
Remove duplicate inputs block that broke ci.yml YAML parsing.
Replace invalid toLower() calls with plain contains() which is
already case-insensitive in GitHub Actions expressions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: regenerate pnpm-lock.yaml for memory-mongodb extension
Add lockfile entries for mongodb, @sinclair/typebox, and openai
dependencies from extensions/memory-mongodb/package.json.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style: apply oxfmt formatting to all ported files
Run oxfmt --write on all 26 files flagged by CI format check,
including mongodb extension, docs, workflows, and gateway files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add logger to voice-call context types and fix markdown lint
- Add logger field to CallManager class and getContext() method
- Add logger to Pick types (InitiateContext, ConversationContext,
MaxDurationTimerContext) so ctx.logger compiles
- Add defaultLogger to events.test.ts context factory
- Wrap bare URLs in docs/deployments.md with angle brackets (MD034)
- Add blank lines before fenced code blocks in staging-setup.md (MD031)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* style: format outbound.ts Pick type for line length
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add logger to EventContext Pick type in voice-call events
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: wrap single-statement if body in braces (lint rule)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: update tests for DAISy branding and deleted smoke files
- Update browser config/utils tests to expect 'daisy' profile name
instead of 'openclaw' (DAISy rebranding)
- Fix approval-id test mock to handle system.run.prepare and proper
approval registration flow (ask defaults to 'always')
- Remove deleted install-sh-smoke Dockerfile from digest test array
- Remove dead test:install:smoke script from package.json
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: update mongodb-provider test mock for refactored init
- Add command() to db mock (doInitialize now pings admin db)
- Remove $match pipeline assertion (filtering moved to JS)
TODO: replace mocked tests with integration tests against real
MongoDB instance to validate actual connectivity.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: restore AGENTS.md and CLAUDE.md from upstream
These were incorrectly deleted during the rebase and added to
.gitignore. Upstream's versions are restored as-is. A future
Patchbot task will replace these with thin, DAISy-specific
versions that minimize token overhead for agents.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test(gateway): enforce least-privilege scopes in e2e tests
Pass explicit minimum scopes to gateway e2e test clients instead of
relying on the default scope. Mock OpenAI test needs admin+write,
wizard test needs admin+read.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: stop tracking .claude/settings.json
Add .claude/settings.json to .gitignore and remove from index.
This file is modified locally by Claude Code during sessions and
causes checkout conflicts between branches.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* revert: restore upstream vitest.config.ts
Our fileParallelism:false and worker changes were causing the Linux
test suite to hang (2h+) and triggering widespread mock resolution
failures across dozens of test files. Restore upstream config which
runs tests in parallel with forks pool.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: resolve pre-existing CI failures blocking merge
- Bun: update 1.3.9+cf6cdbbba → 1.3.10 (old binary returns 404)
- iOS: fix Clawdis → OpenClaw naming in ci.yml to match project.yml
- bluebubbles: use explicit relative path in test instead of
path.relative() which returns absolute on cross-drive Windows
- deps: bump hono 4.11.10 → 4.12.4 and tar 7.5.9 → 7.5.10
to fix audit HIGH/CRITICAL advisories (lockfile regen needed)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: untrack lockfile and disable frozen-lockfile
Remove pnpm-lock.yaml from git tracking (already in .gitignore).
The fork's pnpm.overrides and extension deps diverge from upstream,
making the lockfile a source of friction rather than safety. CI now
resolves fresh from package.json on each run.
Disable --frozen-lockfile default since there is no lockfile to
freeze against.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: remove all --frozen-lockfile references and lockfile COPY commands
The fork diverges from upstream's dependency tree (pnpm.overrides,
custom extensions), so we don't track pnpm-lock.yaml. Remove
--frozen-lockfile from all Dockerfiles, scripts, and CI, and
remove pnpm-lock.yaml from COPY commands since the file won't
exist in the build context.
Files changed:
- Dockerfile: remove --frozen-lockfile and pnpm-lock.yaml COPY
- scripts/e2e/Dockerfile: same
- scripts/e2e/Dockerfile.qr-import: remove --frozen-lockfile
- scripts/docker/cleanup-smoke/Dockerfile: both
- scripts/codex-setup.sh: simplify install (no lockfile guard)
- scripts/codex-maintenance.sh: same
- scripts/pr: remove --frozen-lockfile from bootstrap
- .github/workflows/ci.yml: Windows install step
- src/dockerfile.test.ts: update assertion to match Dockerfile
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: disable iOS CI job and add @hono/node-server audit override
- Disable iOS job (DAISy does not ship an iOS app)
- Add @hono/node-server@1.19.10 pnpm override to fix
GHSA-wc8c-qw6v-h7f6 (authorization bypass via encoded slashes)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: replace upstream AGENTS.md with thin DAISy rules
The 257-line upstream AGENTS.md contains OpenClaw-specific instructions
(exe.dev VMs, 1Password publishing, macOS app ops) irrelevant to DAISy.
Replace with ~20 lines of DAISy-specific, non-inferable rules that are
maintained as a known customization across upstream upgrades.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Agent <agent@example.com>
Co-authored-by: Jonathan Jing <achillesjing@gmail.com>
Co-authored-by: Barron Roth <barronlroth@gmail.com>
Co-authored-by: Altay <altay@hey.com>
Co-authored-by: edincampara <142477787+edincampara@users.noreply.github.com>
Co-authored-by: Charles Dusek <cgdusek@gmail.com>
Co-authored-by: SidQin-cyber <sidqin0410@gmail.com>
Co-authored-by: liuxiaopai-ai <73659136+liuxiaopai-ai@users.noreply.github.com>
Co-authored-by: Glucksberg <markuscontasul@gmail.com>
Co-authored-by: synchronic1 <synchronic1@users.noreply.github.com>
Co-authored-by: Mariana Sinisterra <mariana.data@outlook.com>
Co-authored-by: efe-arv <efe@arven.digital>
Co-authored-by: theotarr <theotarr@users.noreply.github.com>
Co-authored-by: liuxiaopai-ai <liuxiaopai-ai@users.noreply.github.com>
Co-authored-by: Benedikt Johannes <benedikt.johannes.hofer@gmail.com>
Co-authored-by: benediktjohannes <253604130+benediktjohannes@users.noreply.github.com>
Co-authored-by: shakkernerd <165377636+shakkernerd@users.noreply.github.com>
Co-authored-by: Shakker <shakkerdroid@gmail.com>
Co-authored-by: haosenwang1018 <1293965075@qq.com>
Co-authored-by: taw0002 <webmaster@sodsolutions.com>
Co-authored-by: Ho Lim <subhoya@gmail.com>
Co-authored-by: yfge <geyunfei@gmail.com>
Co-authored-by: Frank Yang <frank.ekn@gmail.com>
Co-authored-by: 不做了睡大觉 <64798754+stakeswky@users.noreply.github.com>
Co-authored-by: User <user@example.com>
Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
Co-authored-by: Kevin Wang <kevin@example.com>
Co-authored-by: scoootscooob <zhentongfan@gmail.com>
Co-authored-by: Beer van der Drift <beerdrift@gmail.com>
Co-authored-by: StingNing <810793091@qq.com>
Co-authored-by: ningding97 <17723822+ningding97@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Co-authored-by: SaucePackets <33006469+SaucePackets@users.noreply.github.com>
Co-authored-by: Sense_wang <167664334+haosenwang1018@users.noreply.github.com>
Co-authored-by: charo <charocodeo@gmail.com>
Co-authored-by: charojo <4084797+charojo@users.noreply.github.com>
Co-authored-by: BlueBirdBack <126304167+BlueBirdBack@users.noreply.github.com>
Co-authored-by: C. Liao <51533973+liaosvcaf@users.noreply.github.com>
Co-authored-by: FlamesCN <cool1982405@gmail.com>
Co-authored-by: FlamesCN <12966659+FlamesCN@users.noreply.github.com>
Co-authored-by: zerone0x <hi@trine.dev>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Ash (Bug Lab) <ash@openclaw-lab>
Co-authored-by: Pushkar Kathayat <pushkarsingh32@gmail.com>
Co-authored-by: dhananjai1729 <dhananjaikrishnakumarpm@Dhananjais-MacBook-Pro.local>
Co-authored-by: dhananjai1729 <dhananjaikrishnakumarpm@pool-100-10-9-127.prvdri.fios.verizon.net>
Co-authored-by: Glucksberg <80581902+Glucksberg@users.noreply.github.com>
Co-authored-by: openperf <openperf@users.noreply.github.com>
Co-authored-by: YUJIE2002 <yujie2002@users.noreply.github.com>
Co-authored-by: Ayane <wangruofei@soulapp.cn>
Co-authored-by: Arthur Freitas Ramos <arthur@192.168.0.14>
Co-authored-by: Phineas1500 <sriram.kiron@gmail.com>
Co-authored-by: Jose E Velez <jose.velez363@gmail.com>
Co-authored-by: jose-velez <10926182+jose-velez@users.noreply.github.com>
Co-authored-by: codertony <codertony@users.noreply.github.com>
Co-authored-by: scoootscooob <scoootscooob@users.noreply.github.com>
Co-authored-by: byungsker <byungsker@users.noreply.github.com>
Co-authored-by: Ken <ken@ipl31.net>
Co-authored-by: stozo04 <stozo04@users.noreply.github.com>
Co-authored-by: Sid-Qin <Sid-Qin@users.noreply.github.com>
Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
Co-authored-by: Brian Le <brian@brianle.xyz>
Co-authored-by: Rylen Anil <rylen.anil@gmail.com>
Co-authored-by: Hyup <bosuksh@lguplus.co.kr>
Co-authored-by: root <root@vultr.guest>
Co-authored-by: haosenwang1018 <haosenwang1018@users.noreply.github.com>
Co-authored-by: 李肖然 <lixiaoran@lixiaorandeMacBook-Air.local>
Co-authored-by: williamos-dev <williamos-dev@users.noreply.github.com>
Co-authored-by: stakeswky <stakeswky@users.noreply.github.com>
Co-authored-by: BlueBirdBack <BlueBirdBack@users.noreply.github.com>
Co-authored-by: novan <novan@users.noreply.github.com>
Co-authored-by: lbo728 <extreme0728@gmail.com>
Co-authored-by: graysurf <10785178+graysurf@users.noreply.github.com>
Co-authored-by: Dale Babiy <42547246+minupla@users.noreply.github.com>
Co-authored-by: 倪汉杰0668001185 <ni.hanjie@xydigit.com>
Co-authored-by: Ayaan Zaidi <zaidi@uplause.io>
Co-authored-by: Stxle2 <166609401+Stxle2@users.noreply.github.com>
Co-authored-by: Clawborn <tianrun.yang@hotmail.com>
Co-authored-by: sunkinux <sunkinux@users.noreply.github.com>
Co-authored-by: Charles Dusek <38732970+cgdusek@users.noreply.github.com>
Co-authored-by: Anandesh Sharma <30695364+Anandesh-Sharma@users.noreply.github.com>
Co-authored-by: Kros Dai <xdanger@gmail.com>
Co-authored-by: yuxh1996 <yuxh1996@users.noreply.github.com>
Co-authored-by: bmendonca3 <208517100+bmendonca3@users.noreply.github.com>
Co-authored-by: Mark L <73659136+markliuyuxiang@users.noreply.github.com>
Co-authored-by: cyb1278588254 <48212932+cyb1278588254@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
sachinkundu
pushed a commit
to sachinkundu/openclaw
that referenced
this pull request
Mar 6, 2026
…enclaw#24355) (openclaw#24435) thanks @hugenshen Verified: - pnpm install --frozen-lockfile - pnpm check - pnpm test -- --run src/cron/service.issue-regressions.test.ts src/config/config-misc.test.ts Co-authored-by: hugenshen <16300669+hugenshen@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
sachinkundu
pushed a commit
to sachinkundu/openclaw
that referenced
this pull request
Mar 6, 2026
…aw#31079) * changelog: credit @BUGKillerKing for openclaw#29315 * changelog: credit @liuweifly for openclaw#14674 * changelog: credit @Sid-Qin for openclaw#29709 * changelog: credit @lailoo for openclaw#21808 * changelog: credit @openperf for openclaw#26259 * changelog: credit @icesword0760 for openclaw#28959 * changelog: credit @cowboy129 for openclaw#28529 * changelog: credit @yfge for openclaw#17798 * changelog: credit @kcinzgg for openclaw#27325 * changelog: credit @guoqunabc for openclaw#28494 * changelog: credit @WilsonLiu95 for openclaw#12755 * changelog: credit @qiangu for openclaw#18529 * changelog: credit @lailoo for unreleased openclaw#27616 * changelog: credit @tumf for unreleased openclaw#18642 * changelog: normalize unreleased openclaw#24789 credit handle * changelog: fill unreleased openclaw#24435 credit * changelog: fill unreleased openclaw#25090 credit * changelog: fill unreleased openclaw#29098 credit (entry 1) * changelog: fill unreleased openclaw#29098 credit (entry 2) * changelog: credit @liuxiaopai-ai for unreleased openclaw#30567 * changelog: credit @graysurf for unreleased openclaw#23169 * changelog: credit @pablohrcarvalho for unreleased openclaw#10686 * changelog: credit @Glucksberg for unreleased openclaw#21715 * changelog: credit @liuxiaopai-ai for unreleased openclaw#30586 * changelog: add missing credits for 2026.2.26 * changelog: add missing credits for 2026.2.25 * changelog: add missing credits for 2026.2.24 * changelog: add missing credits for 2026.2.23 * changelog: add missing credits for 2026.2.22
zooqueen
added a commit
to hanzoai/bot
that referenced
this pull request
Mar 6, 2026
…enclaw#24355) (openclaw#24435) thanks @hugenshen Cherry-pick of upstream ea3955c.
zooqueen
pushed a commit
to hanzoai/bot
that referenced
this pull request
Mar 6, 2026
…enclaw#24355) (openclaw#24435) thanks @hugenshen Verified: - pnpm install --frozen-lockfile - pnpm check - pnpm test -- --run src/cron/service.issue-regressions.test.ts src/config/config-misc.test.ts Co-authored-by: hugenshen <16300669+hugenshen@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
zooqueen
pushed a commit
to hanzoai/bot
that referenced
this pull request
Mar 6, 2026
…aw#31079) * changelog: credit @BUGKillerKing for openclaw#29315 * changelog: credit @liuweifly for openclaw#14674 * changelog: credit @Sid-Qin for openclaw#29709 * changelog: credit @lailoo for openclaw#21808 * changelog: credit @openperf for openclaw#26259 * changelog: credit @icesword0760 for openclaw#28959 * changelog: credit @cowboy129 for openclaw#28529 * changelog: credit @yfge for openclaw#17798 * changelog: credit @kcinzgg for openclaw#27325 * changelog: credit @guoqunabc for openclaw#28494 * changelog: credit @WilsonLiu95 for openclaw#12755 * changelog: credit @qiangu for openclaw#18529 * changelog: credit @lailoo for unreleased openclaw#27616 * changelog: credit @tumf for unreleased openclaw#18642 * changelog: normalize unreleased openclaw#24789 credit handle * changelog: fill unreleased openclaw#24435 credit * changelog: fill unreleased openclaw#25090 credit * changelog: fill unreleased openclaw#29098 credit (entry 1) * changelog: fill unreleased openclaw#29098 credit (entry 2) * changelog: credit @liuxiaopai-ai for unreleased openclaw#30567 * changelog: credit @graysurf for unreleased openclaw#23169 * changelog: credit @pablohrcarvalho for unreleased openclaw#10686 * changelog: credit @Glucksberg for unreleased openclaw#21715 * changelog: credit @liuxiaopai-ai for unreleased openclaw#30586 * changelog: add missing credits for 2026.2.26 * changelog: add missing credits for 2026.2.25 * changelog: add missing credits for 2026.2.24 * changelog: add missing credits for 2026.2.23 * changelog: add missing credits for 2026.2.22
Mateljan1
pushed a commit
to Mateljan1/openclaw
that referenced
this pull request
Mar 7, 2026
…enclaw#24355) (openclaw#24435) thanks @hugenshen Verified: - pnpm install --frozen-lockfile - pnpm check - pnpm test -- --run src/cron/service.issue-regressions.test.ts src/config/config-misc.test.ts Co-authored-by: hugenshen <16300669+hugenshen@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
schedule.kind: "at") failed with no retry on transient errors (rate limit 429, network, 5xx), permanently disabling the job.deleteAfterRun: truejobs were silently and permanently lost.applyJobResultnow classifies errors as transient vs permanent and schedules retries with exponential backoff (up to 3 attempts, 30s → 1m → 5m) for one-shot jobs.isRunnableJobupdated to allow retry runs to resume correctly after a gateway restart. Newcron.retryconfig key (maxAttempts, backoffMs, retryOn) for overriding defaults. Docs, schema, labels, and help text updated.cron/every) behavior is completely unchanged.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
cron.retryto override defaults (maxAttempts, backoffMs, retryOn).deleteAfterRun: truejobs still get deleted on success (including after retry); on exhausted retries they are disabled but kept in the store for error inspection.Security Impact (required)
Evidence
cron.retryconfigdeleteAfterRun: truejob deleted after successful retryCompatibility / Migration
cron.retrykey (omit = previous behavior preserved)Failure Recovery (if this breaks)
cron.retry.maxAttempts: 0in config to revert to old immediate-disable behaviorsrc/cron/service/timer.tsRisks and Mitigations
cron.retry.maxAttempts: 0to opt out.Greptile Summary
Added retry logic for one-shot cron jobs (
schedule.kind: "at") to handle transient errors (rate limits, network issues, 5xx errors) with exponential backoff (30s → 1m → 5m), up to 3 attempts by default. Permanent errors (auth failures, invalid config) still disable immediately. The retry behavior is configurable viacron.retryconfig (maxAttempts, backoffMs, retryOn). Recurring jobs remain unchanged. Implementation includes transient error classification via regex patterns, retry scheduling inapplyJobResult, and updates toisRunnableJobto allow retries after restart. Comprehensive test coverage (5 new tests) and documentation updates included.Confidence Score: 5/5
Last reviewed commit: f01d55e
(2/5) Greptile learns from your feedback when you react with thumbs up/down!