NanoClaw 2026.10.0-rc.1 is the release candidate for 2026.10.0, the first release with calendar version numbers and the first one /update-nanoclaw installs by default: updates now follow published releases instead of the tip of main. Installs on the beta channel get this candidate; stable stays on 2.4.0 until 2026.10.0 is published. It also makes updates and rollbacks more dependable, lets Iron Proxy reach a keyless local model over plain HTTP, routes the service through an outbound proxy when you have one, and shows Claude's own reason when a run fails. Iron Proxy installs need one setup rerun, so check the section below before you update.
⚠️ Before you update
- [BREAKING] OneCLI installs: upgrade the OneCLI gateway to 1.42.0, which closes a credential-injection bypass.
/update-nanoclawnever upgrades a running gateway, so this step stops the update until it is done. Skip it if.envhas noONECLI_URL(Iron Proxy installs). Otherwise follow docs/onecli-upgrades.md: run its detect step, upgrade to theonecli-gatewayversion inversions.json(1.42.0), verify, and note the old version for its rollback step. New installs already get 1.42.0. /update-nanoclawnow installs the newest release, not the tip ofmain. The channel is set byNANOCLAW_UPDATE_CHANNELin.env:stable(the default) follows releases,edgefollowsmainas before, andbetatakes release candidates when there are any. Your first update after this release still runs your current update steps, so it lands on the tip ofmain, which is this release only until new changes merge; from then on, updates follow the channel. An install that is already newer than the latest release is never moved back: the updater asks whether to keep followingmainor wait for the next release, and saves the answer. To choose yourself later, runpnpm exec tsx scripts/update-nanoclaw.ts set-channel --channel edge(orstable).- Iron Proxy installs: rerun the Iron setup once after updating. It rebuilds the proxy on upstream v0.52.0 (expired proxy certificates are regenerated, host rules match case-insensitively), moves the approval bridge to
@grpc/grpc-js1.14.5 (fixes GHSA-m9gg-hp2v-232j and GHSA-f596-whhp-79r4), and letsgit clone/fetchand the agent browser authenticate through the proxy. Runpnpm exec tsx .claude/skills/add-iron-proxy/scripts/setup.ts --with-control. HTTPS pages behind Iron still fail in the agent browser until it trusts the gateway's certificate; that fix is not in this candidate. OneCLI installs need nothing.
✨ New
- Updates follow release channels. Choose
stable,betaoredgeper install; the channel and the exact release are recorded indata/upgrade-state.json, so support can see what an install tracks. - With Iron Proxy, a keyless model on the same machine works over plain HTTP. Enter
http://host.docker.internal:<port>/v1and restart; setup checks that the port answers like a model server, only that port and the OpenAI inference routes are reachable, and requests to it no longer ask for approval on every call. Models that need a key still needhttps://on a public DNS name. - The service can reach the internet through an outbound proxy. It now uses
HTTPS_PROXY,HTTP_PROXYorALL_PROXYandNO_PROXYfrom your setup shell or.env; a OneCLI gateway on a local address is added toNO_PROXYautomatically. Needs Node 22.21+ or 24.5+, and setup warns if your Node ignores the proxy. - A failed Claude run tells you why. For known failures such as an invalid API key, the chat shows Claude's short message (for example "Invalid API key · Fix external API key") and who can fix it, instead of "The agent run failed".
🛠️ Fixes
/update-nanoclawis more dependable. A failed update no longer deletes half ofdata/when it rolls back: the snapshot is swapped in by rename, and if a restore still fails nothing is deleted and the error prints the commands that finish it. It works again from 2.4.0 (it stopped with "Cannot find module"), detects the installed gateway even when pnpm prints a warning, keeps Iron Proxy running across the update, and no longer reports success while the old service is still running. A rollback now stops the host that is actually running and stops agent containers before restoring your data. Updates that bring a new tsx or esbuild no longer crash at the end of cutover on installs with a gateway (the fix is in the update controller, so it covers the update that brings it). A fresh install can now be updated without manual commits: setup commits the files it adds as localsetup: apply <skill>commits (setNANOCLAW_SETUP_COMMIT=0to skip them). When an update changes only your gateway's skill files, it now refreshes the gateway's host code too.- Claude turns are cheaper again. New Claude groups no longer default to the
Conciseoutput style, which stopped the prompt cache from reading the conversation back, so every turn paid to cache it again; the concise instruction now lives in the agent'sCLAUDE.md. A group that already hasConcisekeeps it: setoutputStyletodefault(or delete the key) indata/v2-sessions/<agent-group-id>/.claude-shared/settings.json. - Agents behave better in chats. The typing indicator stays on while Claude writes a long answer, agents no longer trade "The agent run failed" messages with each other forever, and they read each turn's subject from their own message and history, asking when a bare "this" is ambiguous. Deleting an agent with
ncl groups deletenow stops its container within about a minute. - Setup is clearer when something goes wrong. A failing skill step shows its own reason, Codex and OpenCode installs are no longer offered the Claude CLI, a failed host restart says why the host is not ready, and the setup log records whether the assistant answered the first test message. OpenCode setup checks a local model URL against your gateway at the prompt, Iron Proxy setup skips a malformed allowlist entry and says how to fix it, and on arm64 Linux it stops early, with the command to turn on emulation, when Docker cannot run the Iron Control image. Setup's OneCLI step works under a strict
077umask, and uninstalling removes the Iron Control database so a reinstall in the same folder starts clean. - Smaller fixes. OpenCode agents avoid a Bun hang in the memory hook;
send_cardno longer breaks requests to llama.cpp-served models (non-ASCII link URLs are encoded automatically); OneCLI credential errors during setup name the credential being set up instead of always saying "OpenCode"; a scheduled-task pre-script that hits its 30 s timeout now stops its child processes too; logging a circular object or a BigInt no longer crashes the host;ncl approvals helpandncl dropped-messages helplist exactly the values the host writes; Node 26 no longer prints amodule.register()warning; and the/add-imessagelocal backend on a Mac openschat.dbagain (if you installed it before, rerun/add-imessageand chooselocal).
🔒 Security
- Setup's debugging helper asks before it runs commands or edits files. Claude's headless helper is read-only.
- Outbound proxy settings, which can include a password, are kept in an owner-only file instead of the service definition. If you use an authenticated proxy, rerun setup's service step (
pnpm exec tsx setup/index.ts --step service) to move it out of your existing service file. - Discord's local event relay only accepts events from NanoClaw's own Discord connection, so other programs on the same machine can no longer send it fake button clicks. No action needed.
🔧 For custom installations
- Version numbers are now calendar-based (
YYYY.M.PATCH). 2026.10.0 follows 2.4.0 and sorts after it, so tools that compare versions keep working; a dependency range such as^2will not match it. Release tags stayvX.Y.Zand annotated. - Forks that merge
mainby hand can keep doing so; to keep/update-nanoclawonmaininstead of releases, runpnpm exec tsx scripts/update-nanoclaw.ts set-channel --channel edgeonce. - Provider contracts can list exact model endpoints. A provider skill sets
modelAuthoritiestohost:portpairs that skip the gateway's default approval, asmodelDomainsdoes for whole domains. - The published agent image is unchanged in this release. Installs that pull the image keep the 2026-08-25 build; the agent-runner dependency refresh in this release reaches them with the next image, built from this release's tag. Installs that build the image locally get it now.
New Contributors
- @barnuri made their first contribution in #3895
- @daviddl9 made their first contribution in #3969
- @drsmk238 made their first contribution in #3989
Contributors
Thanks to everyone who landed work in this release:
- fix(cli): list every approval status and drop reason the host writes by @glifocat in #3882
- feat(agent-runner): explain inbound message blocks in the chat system prompt by @Koshkoshinsk in #3890
- fix: seed Claude's default output style, not Concise, which defeated prompt caching by @gavrielc in #3917
- fix(agent-runner): keep send_card url pattern parseable by llama.cpp grammars by @barnuri in #3895
- fix(iron-proxy): skip invalid allowed-hosts entries instead of aborting setup by @glifocat in #3915
- fix(cli): drop unknown_sender_public from the dropped-messages reason list by @glifocat in #3889
- test(community-portal): wait for the journal to clear instead of sleeping by @glifocat in #3892
- fix(agent-runner): keep the heartbeat alive while Claude streams a long block by @glifocat in #3893
- fix(setup): keep the Claude CLI offer to Claude installs by @glifocat in #3884
- test(webhook): recover on the fixture-owned port by @glifocat in #3803
- fix(update): load the update controller without setup/ or node_modules by @glifocat in #3913
- fix(agent-runner): never answer a failure notice with another by @glifocat in #3908
- fix(opencode): run the memory hook with async spawn so bun test cannot wedge by @glifocat in #3841
- fix(setup): log the first-chat ping result and the real OpenCode auth duration by @glifocat in #3905
- fix(setup): never clip a readiness probe to the deadline by @glifocat in #3887
- fix(setup): detect installed gateways without parsing nested pnpm output by @glifocat in #3910
- test(delivery): seed one session past the cap in the drain test by @glifocat in #3945
- fix(skill-apply): show a failed step's own error instead of a generic bounce by @glifocat in #3946
- fix(update): keep gateway-owned containers through cutover and residue reaping by @glifocat in #3948
- test(agent-runner): spawn bun children asynchronously so CI stops hanging in spawnSync by @glifocat in #3959
- fix(add-onecli): name the credential, not the provider, in adapter errors by @glifocat in #3960
- fix(scheduling): kill the whole process group when a pre-task script times out by @glifocat in #3957
- fix(setup): restrict failure-assist agents on a live install by @glifocat in #3920
- fix(iron-proxy): remove Iron Control's database on uninstall by @glifocat in #3883
- fix(host): stop containers whose session or agent group was deleted by @glifocat in #3947
- fix(iron-proxy): stop early on arm64 engines that cannot run amd64 images by @glifocat in #3953
- docs(gateways): correct what the credential reread refuses in two comments by @glifocat in #3954
- docs(opencode): keep gateway notes in the gateway skills by @glifocat in #3955
- fix(log): never throw when a log value cannot be JSON-serialized by @glifocat in #3958
- fix(update): refuse cutover when the service liveness probe itself fails by @glifocat in #3962
- fix(container): refresh agent-runner lockfile to clear transitive advisories by @glifocat in #3974
- fix(update): rollback stops the live nohup host and drains agent containers by @glifocat in #3956
- feat(gateway): let a provider declare exact host:port model endpoints by @glifocat in #3964
- fix(opencode,iron): check the model URL against the selected gateway at the prompt by @glifocat in #3965
- feat(iron): allow a keyless model on this machine over plain HTTP by @glifocat in #3966
- ci: pin workflow actions and cosign to exact versions by @glifocat in #3968
- fix(setup): let the host service reach the internet through an HTTPS proxy by @barnuri in #3901
- build(deps): bump tsx to 4.23 to stop Node 26 module.register warning by @glifocat in #3977
- test(onecli): make unsafe-directory permissions test umask-independent by @glifocat in #3979
- build(deps): bump grpc to 1.83.2 in the Iron front proxy by @glifocat in #3981
- build(deps): pin Iron Proxy to v0.52.0 by @glifocat in #3982
- test(update): remove the data symlink with unlinkSync, not rmSync by @tchopoorian in #3963
- fix(agent-runner): show the Claude SDK's own failure notice instead of the generic one by @glifocat in #3994
- fix(iron-proxy): send a Basic challenge with the front proxy's 407 by @daviddl9 in #3969
- fix(update): restore the snapshot by rename so a rollback never half-deletes data/ by @glifocat in #4012
- feat(release): self-approved x.y.z-rc.N pre-releases; widen stable approvers by @glifocat in #3987
- fix(setup): keep proxy credentials out of readable service files by @glifocat in #3985
- fix(setup): commit applied skill files so a fresh install can update by @glifocat in #3997
- build(deps): bump @grpc/grpc-js to 1.14.5 in the Iron approval bridge by @glifocat in #4005
- fix(onecli): pin the gateway to 1.42.0 for the host-enforcement bypass fix by @drsmk238 in #3989
- fix(chat-sdk): authenticate the loopback Gateway webhook by @glifocat in #4013
- test(setup): mirror host pnpm patches and overrides in the nested-pnpm probe by @glifocat in #4001
- fix(add-imessage): open chat.db under Node with core's prebuilt better-sqlite3 by @glifocat in #4008
- ci(labels): run the area labeler after label-pr, not in parallel by @glifocat in #3912
- fix(update): load gateway helpers before cutover swaps node_modules by @glifocat in #4016
- docs(contributing): write down the core-or-fork rule by @glifocat in #4011
- fix(update): refresh the installed gateway when only its skill payload changed by @glifocat in #3988
- feat(update): follow release tags by default via update channels by @glifocat in #3986
- chore(release): v2026.10.0-rc.1 by @glifocat in #4025
Full Changelog: v2.4.0...v2026.10.0-rc.1