#How to get my agent to check session history and pick up where it left off after gateway restart?
1 messages Ā· Page 1 of 1 (latest)
Let me verify the actual docs and resume behavior instead of guessing.
BOOTSTRAP.md is the wrong lever here, that file is first-run only. BOOT.md is the startup hook, but there are 2 important gotchas:
-
You must enable the boot-md hook itself, not just
hooks.internal.enabledopenclaw hooks enable boot-md openclaw hooks list openclaw gateway restartDocs: https://docs.openclaw.ai/cli/hooks and https://docs.openclaw.ai/automation/hooks#boot-md
-
Even when
BOOT.mdruns, it is a fresh startup check, not a true āresume the interrupted run exactly where it stoppedā feature.
A few useful distinctions:
- Normal chat/session history should already survive a gateway restart. It lives on disk under
~/.openclaw/agents/<agentId>/sessions/.
Docs: https://docs.openclaw.ai/concepts/session - If history seems gone after restart, it is usually one of:
- different state dir/profile
- non-persistent container/volume
- different thread/channel, so different session key
- session rotation (daily reset at 4am gateway-host local time, or idle reset)
If your goal is specifically resume Codex / Claude Code / ACP work after restart, the real feature for that is ACP resumeSessionId, not BOOT.md.
Docs: https://docs.openclaw.ai/tools/acp-agents#resume-an-existing-session
If you want, paste these and I can narrow it down fast:
openclaw status --all
openclaw hooks list
Also say whether this is:
- a normal OpenClaw chat session, or
- an ACP/Codex/Claude session.
normal openclaw chat. my goal is for after the gateway restart agents have warmed up to system event send them a message to send me a message either saying "hey i'm back" and/or checking the last message and trying to figure out why the gateway restarted if it wasn't expected.
Let me verify one detail here, BOOT.md startup runs in the main session, so if you want it to inspect other chats it likely needs to use the session tools explicitly.
Ah, got it, for that goal BOOT.md is actually pretty close, but thereās a hidden gotcha:
BOOT.md runs in the agentās main session, not in the last Discord thread/session by default.
So if you want it to:
- look at the last real user-facing session,
- inspect recent history there,
- then proactively message you there,
you usually need session tools too, not just a BOOT.md file.
What Iād set up
- Enable the startup hook
openclaw hooks enable boot-md
-
Let the agent see other sessions for the same agent
{ tools: { sessions: { visibility: "agent" } } }Default is only
tree, which usually means the BOOT run cannot inspect arbitrary chat sessions. -
If you use a tool allowlist, allow session tools
sessions_listsessions_historysessions_send
Why this matters
Your BOOT run can then do something like:
sessions_listā find the most recent real chat sessionsessions_historyā inspect the last few messagessessions_sendā inject a āhey, Iām backā / recovery message into that session
Thatās better than trying to have BOOT.md magically inherit the old thread context, because it doesnāt.
A BOOT.md shape that should work
Something like:
On gateway startup:
1. Use sessions_list to find the most recent non-hook, non-cron user-facing session for this agent.
2. Use sessions_history to inspect the last 8-12 messages.
3. If the last exchange looks interrupted, use sessions_send to that session with a short recovery message:
"Hey, I'm back after a gateway restart. I was last working on <brief summary>."
4. If the restart looks unexpected, inspect available restart context and recent session history, then include a short guess about what may have happened.
5. If nothing needs attention, do nothing.
Important limitation
For āwhy did the gateway restart?ā, chat history alone is weak evidence.
If you want a real diagnosis, the BOOT run should also inspect the latest logs or restart sentinel data, which means exec/file access has to be allowed.
One more nuance
For planned /restart-style restarts, OpenClaw already has a built-in restart sentinel wake-up path.
BOOT.md is more useful for the broader āI came back up, inspect things and proactively recoverā behavior.
Docs:
- https://docs.openclaw.ai/automation/hooks#boot-md
- https://docs.openclaw.ai/concepts/session-tool
- https://docs.openclaw.ai/gateway/configuration-reference
If you want, paste your current BOOT.md and Iāll help rewrite it into one that matches this flow.
Iād keep it tight, bounded, and boring. BOOT.md works better as a single recovery pass than as a vague āfigure stuff outā prompt.
Good robust BOOT.md
# BOOT.md
On gateway startup, do exactly one bounded recovery pass.
Goal:
- If a recent user-facing conversation may have been interrupted by the restart, send one short follow-up in that same session.
- Otherwise do nothing.
Instructions:
1. Use `sessions_list` to inspect recent sessions for this agent.
2. Ignore non-user-facing sessions when possible, especially hook, cron, and obviously internal sessions.
3. Choose the single most relevant recent user-facing session, preferring:
- most recent activity
- Discord/thread or other chat session with a real human
- sessions that look interrupted or unanswered
4. Use `sessions_history` on that session and inspect only the recent messages.
5. If the last exchange looks interrupted, unresolved, or like the user was waiting on you, use `sessions_send` to send one concise recovery message to that session.
6. If the last exchange looks complete, do not send anything.
7. If you can infer a likely restart-related issue from available context, include one short sentence, but do not guess wildly.
8. Never send more than one proactive message on startup.
9. Do not loop, poll, or spawn sub-agents.
10. If nothing needs attention, reply with only `NO_REPLY`.
Style for any proactive message:
- brief
- calm
- specific
- no long recap
Example message:
"Hey, I'm back after a gateway restart. It looks like we were in the middle of <topic>. Want me to continue from there?"
If you want the āwhy did I restart?ā part too
Only add this if the agent is allowed to inspect logs/restart state:
11. If log or restart-sentinel context is available, inspect only a small recent slice.
12. Mention a likely cause only when there is concrete evidence.
13. If the cause is unclear, say so plainly.
Important config around this
Youāll usually also want:
{
tools: {
sessions: {
visibility: "agent"
}
}
}
And if you use a tool allowlist, include:
sessions_listsessions_history
sessions_send
Also make sure the hook is enabled:
openclaw hooks enable boot-md
If you want, I can also give you a more opinionated BOOT.md tuned specifically for Discord threads.
can i set tools.sessions.visibility for a specific agent in agents.list?
Let me verify the config shape before I guess, that oneās easy to get subtly wrong.
Short answer: not directly, no.
From the current config/docs, tools.sessions.visibility is a global setting, not an agents.list[] override.
The closest per-agent thing is:
agents.list[].sandbox.sessionToolsVisibility
but that is only for sandboxed sessions, and it only supports:
"spawned""all"
So it is not a per-agent version of:
tools.sessions.visibility // self | tree | agent | all
Practical workaround
If you want only one agent to do BOOT/recovery work, a good pattern is:
- Set global session visibility broad enough:
{ tools: { sessions: { visibility: "agent" } }
}
- Then only give the session tools to the recovery agent, and deny them on the others.
Example:
{
tools: {
sessions: {
visibility: "agent"
}
},
agents: {
list: [
{
id: "recovery",
tools: {
alsoAllow: ["sessions_list", "sessions_history", "sessions_send"]
}
},
{
id: "normal",
tools: {
deny: ["sessions_list", "sessions_history", "sessions_send"]
}
}
]
}
}
So the visibility is global, but effective access can still be made agent-specific via each agentās tool policy.
Docs:
- https://docs.openclaw.ai/gateway/configuration-reference
- https://docs.openclaw.ai/concepts/session-tool
If you want, I can sketch the exact openclaw.json for a dedicated recovery agent + BOOT.md setup.
tried this. noticed several steps say to do nothing if there's nothing to report, but i want at least a quick and brief "hey i'm back" or something on a clean restart
Yep, then Iād make the clean-restart path explicit.
Something like this is closer to what you want:
# BOOT.md
On gateway startup, do exactly one bounded recovery pass.
Goal:
- Always send one short "I'm back" message to the most relevant recent user-facing session.
- If that session looks interrupted, make the message slightly more specific.
Instructions:
1. Use `sessions_list` to inspect recent sessions for this agent.
2. Ignore hook, cron, and obviously internal sessions.
3. Pick exactly one recent user-facing session, preferring the most recent active one.
4. Use `sessions_history` to inspect the recent messages from that session.
5. If the session looks interrupted or unresolved, use `sessions_send` to send a short recovery message like:
"Hey, I'm back after a gateway restart. It looks like we were in the middle of <topic>. Want me to continue?"
6. If the session does not look interrupted, still use `sessions_send` to send a brief clean-restart message like:
"Hey, I'm back."
7. Never send more than one startup message.
8. Keep the message brief and natural.
9. Do not loop, poll, or spawn sub-agents.
10. If there is no suitable recent user-facing session, reply with only `NO_REPLY`.
A couple tweaks Iād recommend:
- use one target session only, otherwise restart spam gets annoying fast
- maybe mentally treat ārecentā as āactive in the last day or soā
- keep the clean message super short, literally just āHey, Iām back.ā
If you want, I can make this a little smarter for Discord threads, like āprefer the most recent non-empty thread session with a human last message.ā
Yep, absolutely. Just tweak 3 spots in the earlier version.
1. Change the Goal section
Old
Goal:
- If a recent user-facing conversation may have been interrupted by the restart, send one short follow-up in that same session.
- Otherwise do nothing.
New
Goal:
- If a recent user-facing conversation may have been interrupted by the restart, send one short follow-up in that same session.
- Otherwise, if there is a suitable recent user-facing session, send one brief clean-restart message in that session.
2. Change step 6
Old
6. If the last exchange looks complete, do not send anything.
New
6. If the last exchange looks complete, still send one brief clean-restart message such as:
"Hey, I'm back."
3. Change the last step
Old
10. If nothing needs attention, reply with only `NO_REPLY`.
New
10. If there is no suitable recent user-facing session, reply with only `NO_REPLY`.
That preserves the original structure, but gives you the always-send-a-small-ping behavior you want.
perf ty
Nice š
If this ends up fixing it, please right-click the solution message ā Apps ā ā Mark Solution so Answer Overflow can index it for the next person.
restarted but it didn't send me a message in the main private chat
Yeah, that part tracks.
The BOOT.md version we were tweaking was āpick a recent session and message thatā, not āalways DM my main private chat.ā
Also, one subtle thing: BOOT.md itself is silent unless it uses a sending tool. A plain assistant reply from the boot run does not get delivered.
So if you want a guaranteed DM in your main private chat, the BOOT.md should say that explicitly and use the message tool, not session discovery.
Better BOOT.md for that goal
# BOOT.md
On gateway startup:
1. Send a brief "I'm back" message to my main private Discord chat using the `message` tool.
2. Use:
- `channel: "discord"`
- `target: "<my Discord user id or main DM target>"`
3. Message text should be brief, like:
"Hey, I'm back."
4. After sending the message, reply with only `NO_REPLY`.
5. Do not loop, do not poll, and do not send more than one startup message.
If you want both:
- always DM me āhey Iām backā
- and also inspect recent sessions for interrupted work
then do it in that order, but still keep it bounded.
The key point is: if the destination is specifically your main private chat, donāt rely on āfind the best recent session.ā Just hardcode the target via message.
Iād merge it by making the main private chat DM the one guaranteed startup message, and using the session checks only to decide what that one message says.
That keeps the previous structure, plus the later āalways send a brief hey Iām backā edit, without turning startup into 2 messages.
Combined version
# BOOT.md
On gateway startup, do exactly one bounded recovery pass.
Goal:
- Always send one short startup message to my main private Discord chat.
- If a recent user-facing conversation may have been interrupted by the restart, mention that briefly in the same message.
- Otherwise send a brief clean-restart message.
Instructions:
1. Use `sessions_list` to inspect recent sessions for this agent.
2. Ignore non-user-facing sessions when possible, especially hook, cron, and obviously internal sessions.
3. Choose the single most relevant recent user-facing session, preferring:
- most recent activity
- Discord/thread or other chat session with a real human
- sessions that look interrupted or unanswered
4. Use `sessions_history` on that session and inspect only the recent messages.
5. If the last exchange looks interrupted, unresolved, or like the user was waiting on you, send one concise DM to my main private Discord chat using the `message` tool with:
- `channel: "discord"`
- `target: "<my Discord user id or DM target>"`
- message text similar to:
"Hey, I'm back after a gateway restart. It looks like one recent conversation may have been interrupted while we were working on <topic>."
6. If the last exchange looks complete, still send one brief clean-restart DM to my main private Discord chat using the `message` tool with:
- `channel: "discord"`
- `target: "<my Discord user id or DM target>"`
- message text:
"Hey, I'm back."
7. Never send more than one startup message.
8. Keep the message brief and natural.
9. Do not loop, poll, or spawn sub-agents.
10. If sending is not possible or there is no valid private-chat target configured, reply with only `NO_REPLY`.
11. After sending the DM, reply with only `NO_REPLY`.
Why this version is cleaner
- you still get the always-on āhey Iām backā
- you keep the interrupted-session awareness
- you avoid double-notifying yourself
If you want, I can also turn that into a minimal diff against the earlier BOOT.md instead of giving the full merged version.
sure
Nice, hereās the minimal diff version.
1. Replace the Goal block
Old
Goal:
- If a recent user-facing conversation may have been interrupted by the restart, send one short follow-up in that same session.
- Otherwise, if there is a suitable recent user-facing session, send one brief clean-restart message in that session.
New
Goal:
- Always send one short startup message to my main private Discord chat.
- If a recent user-facing conversation may have been interrupted by the restart, mention that briefly in the same message.
- Otherwise send a brief clean-restart message.
2. Replace step 5
Old
5. If the last exchange looks interrupted or unresolved, use `sessions_send` to send one concise recovery message to that session.
New
5. If the last exchange looks interrupted or unresolved, use the `message` tool to send one concise DM to my main private Discord chat with:
- `channel: "discord"`
- `target: "<my Discord user id or DM target>"`
- a brief message like:
"Hey, I'm back after a gateway restart. It looks like one recent conversation may have been interrupted while we were working on <topic>."
3. Replace step 6
Old
6. If the last exchange looks complete, still send one brief clean-restart message such as:
"Hey, I'm back."
New
6. If the last exchange looks complete, use the `message` tool to send one brief clean-restart DM to my main private Discord chat with:
- `channel: "discord"`
- `target: "<my Discord user id or DM target>"`
- message text:
"Hey, I'm back."
4. Replace the final step
Old
10. If there is no suitable recent user-facing session, reply with only `NO_REPLY`.
New
10. If sending is not possible or there is no valid private-chat target configured, reply with only `NO_REPLY`.
11. After sending the DM, reply with only `NO_REPLY`.
That should preserve the original BOOT.md shape while changing the destination from ābest recent sessionā to āalways DM me privately.ā
i kinda liked the previous one's structure better, especially if i'm gonna be the only one using this particular main agent
Yeah, honestly, if youāre the only one using that agent, I agree. The earlier session-first structure is cleaner.
In that case Iād keep it almost exactly as-is, and just make the chosen session prefer your main private chat.
The cleaner tweak
Goal
Use this instead:
Goal:
- Always send one short startup message in the chosen user-facing session.
- Prefer my main private chat when selecting the session.
- If a recent conversation may have been interrupted by the restart, mention that briefly in the same message.
- Otherwise send a brief clean-restart message.
Step 3
Replace with:
3. Choose the single most relevant recent user-facing session, preferring:
- my main private chat
- otherwise the most recent active user-facing session
- sessions that look interrupted or unanswered
Step 5
Use:
5. If the last exchange looks interrupted or unresolved, use `sessions_send` to send one concise recovery message to that chosen session, such as:
"Hey, I'm back after a gateway restart. It looks like we may have been in the middle of <topic>. Want me to continue?"
Step 6
Use:
6. If the last exchange looks complete, still send one brief clean-restart message to that chosen session, such as:
"Hey, I'm back."
Final step
Use:
10. If there is no suitable recent user-facing session, reply with only `NO_REPLY`.
So the overall structure stays the same:
- inspect recent sessions
- pick one
- always send one message there
Just with a stronger preference for your private main chat.
For a single-user agent, thatās probably the nicest version.
still no luck :')
Oof, okay, I think weāre past āprompt wordingā and into plumbing/debugging now š
At this point, please paste these:
openclaw hooks list
openclaw hooks info boot-md
openclaw status --all
and also:
- your current
BOOT.md - the relevant config around:
tools.sessions.visibilityagents.list[]for this agent- any tool allow/deny config
If you can, also restart once and grab any boot-related log lines, especially anything mentioning:
boot:BOOT.mdhookrestart-sentinel
What Iām trying to distinguish
- hook not enabled / not firing
- wrong workspace, so it never sees your
BOOT.md - BOOT.md runs but is skipped (
missing/empty) - BOOT.md runs but tool policy blocks it
- BOOT.md runs and sends, but target session/chat selection is wrong
- Discord delivery fails
If you want the fastest path, paste:
openclaw hooks listopenclaw hooks info boot-md- your actual
BOOT.md
That should be enough to stop guessing.
boot.md is in hooks list, tools.sessions.visibility is "all", agents.list for the agent is elevated and full security.
hooks info boot-md shows "ready" and "run BOOT.md on gateway startup" and some normal looking source/details. requirements config green checkmark workspace.dir
how do i see the boot log? just run log after restart?
Let me check what actually gets logged for BOOT.md outcomes so I donāt send you on a wild goose chase.
Yep, basically that, but Iād do it like this:
Easiest way
Terminal 1
openclaw logs --follow | rg 'boot|boot-md|BOOT.md|restart-sentinel|hook'
Terminal 2
openclaw gateway restart
If openclaw logs --follow is flaky, use the file log directly:
tail -f "$(ls -t /tmp/openclaw/openclaw-*.log | head -1)" | rg 'boot|boot-md|BOOT.md|restart-sentinel|hook'
Important gotcha
A successful BOOT.md run is mostly quiet.
The useful lines are usually only when it fails or gets skipped.
Things worth looking for:
boot-md failed for agent startup runboot: agent run failed: ...boot: failed to read BOOT.md: ...boot-md skipped for agent startup run
If you see nothing
That does not necessarily mean BOOT didnāt run. It can mean it ran successfully but didnāt send anything.
At that point, the best next debug step is a tiny smoke-test BOOT.md, like:
On gateway startup, use the message tool to send a message to <your fixed target> saying:
"boot test"
After sending, reply with only NO_REPLY.
If that doesnāt send, the problem is not your clever BOOT logic, itās one of:
- wrong workspace / wrong BOOT.md
- hook firing path
- message routing/target
- Discord delivery
If you want, paste the exact boot-related log lines after a restart and Iāll help interpret them.
no luck
Ugh, thatās frustrating.
At this point I want to stop guessing and check 2 very concrete things:
- the exact
BOOT.mdcontents - the exact path where that file lives
Reason: for agents in agents.list, the startup hook runs against that agentās resolved workspace, not just the main/global workspace. So if this agent has its own workspace, BOOT.md needs to be in that workspace.
Please paste:
- the agent id
- the relevant
agents.list[]block for that agent (redact secrets) - the exact filesystem path of
BOOT.md - the exact contents of
BOOT.md
And one quick yes/no:
- after restart, did you see any
boot-md/boot:lines at all, or totally nothing?
My current top suspects are:
BOOT.mdis in the wrong workspace for that agent- the file is fine, but the BOOT run is not using the message tool in a way that actually routes
- the boot run is succeeding quietly, but the target/destination is wrong
If you paste the actual file + path, I can be a lot more precise.
agent is using the global .openclaw/workspace. boot.md is too. I don't see anything boot related in the logs right after restart. as for the actual file, it's basically what you gave me plus the last couple of updates.
Wait, one very specific thing jumped out:
You wrote boot.md.
If the file on disk is actually lowercase boot.md, that is very likely the whole problem.
On Linux, OpenClaw looks for exactly:
BOOT.md
uppercase.
A lowercase boot.md would be treated as missing, and that missing case is only logged at debug, which matches what youāre seeing: basically nothing obvious in normal logs.
So first check this exact filename
It should be:
~/.openclaw/workspace/BOOT.md
not:
~/.openclaw/workspace/boot.md
If itās already uppercase, then Iād go straight to the minimal smoke test next. But if itās lowercase, Iām pretty optimistic thatās the bug.
No worries, glad we checked.
Given everything youāve said so far:
- hook is enabled
- workspace is right
BOOT.mdexists- no obvious boot failures in logs
ā¦I actually think the startup hook is probably firing, and we now need to isolate whether the problem is:
- message routing/tool use, or
- BOOT.md execution specifically
Best next test, no clever logic
Test 1: outside BOOT.md
In a normal chat with that same agent, say something like:
Use the message tool to send a Discord DM to <your Discord user id> saying "manual boot test". After sending, reply only NO_REPLY.
If that does not DM you, the issue is not BOOT.md, itās message routing / DM targeting.
Test 2: minimal BOOT.md
Temporarily replace BOOT.md with only this:
On gateway startup, use the message tool exactly once to send a Discord DM to my user id with the text:
"boot test"
Use:
- channel: "discord"
- target: "<my Discord user id>"
After sending, reply with only NO_REPLY.
If sending fails, reply with only NO_REPLY.
Then restart.
How to interpret it
- Test 1 fails ā message tool / Discord DM target problem
- Test 1 works, Test 2 fails ā likely a real
BOOT.md/ startup-hook bug - Both work ā the bigger BOOT.md logic is the problem, and we can rebuild from there
If you hit the middle case, Iād honestly call that a good minimal repro and file it here:
https://github.com/openclaw/openclaw/issues
If you want, after you try those two tests, paste just:
- ātest 1 worked/failedā
- ātest 2 worked/failedā
and Iāll tell you the next move.
test 1 worked. test 2 failed.
I want to sanity-check one last thing, whether āreadyā in hooks output actually means āenabled,ā because those are not always the same.
Ohhh, I think we finally found the missing nuance.
āReadyā is not the same as āenabled.ā
openclaw hooks list / hooks info can show boot-md as ready/eligible, but workspace hooks are disabled by default until you explicitly enable them.
That fits your symptoms really well:
- hook shows up
- requirements are green
BOOT.mdexists- manual send works
- boot test does nothing
- no boot logs
What to do
Explicitly enable it:
openclaw hooks enable boot-md
openclaw gateway restart
Or set it directly in config:
{
hooks: {
internal: {
entries: {
"boot-md": {
enabled: true
}
}
}
}
}
Why Iām pretty optimistic now
The docs literally note that workspace hooks are disabled by default until enabled. So seeing ready was unfortunately a bit misleading here.
If you already did openclaw hooks enable boot-md, then the next thing Iād want is the relevant hooks.internal.entries config block, because at that point weāre into āenabled state not persistingā territory.
But if you havenāt explicitly enabled it yet, Iād bet thatās it.
that piece was already in the json but i ran the command anyways and am currently restarting the gateway
Perfect, thatās the right moment to test.
After it comes back, I only need 2 things from you:
- Did the minimal BOOT test DM you?
- Did any
boot-md/boot:lines appear this time?
If it still does nothing, my next suspicion is that the running gateway service is using a different config/workspace than the one youāre editing, and then Iād want:
openclaw gateway status
openclaw status --all
Hoping this restart finally makes it click š¤
i saw in the log when it was re-enabled (it was already enabled though) but nothing after the restart about boot.md. did a full reboot, no luck. will try more tomorrow
Totally fair, get some sleep š
You actually narrowed it down a lot already:
- manual
messagesend works - minimal
BOOT.mdstartup send does not - you see hook-enable activity in logs
- but nothing boot-related on restart/reboot
That smells much more like a startup hook registration / live config path / service mismatch issue than a bad BOOT.md prompt.
Best next checks for tomorrow
openclaw gateway status
openclaw status --all
And if you can, paste:
- the config path the service says it is using
- the relevant
hooks.internal.entries - whether
BOOT.mdis still in that same workspace path
If it still repros tomorrow, I think youāve got a pretty solid minimal bug report brewing.
Short version: yes, this is absolutely supposed to be a BOOT.md feature.
The intended behavior is:
BOOT.mdexists in the workspaceboot-mdhook is enabled- gateway starts
- OpenClaw runs that startup checklist
That part is real, documented, and in source. So you are not trying to use BOOT.md for something out-of-scope.
Whatās less clear is how battle-tested this specific path is:
- startup hook
- agent run
- tool call
- proactive Discord DM
Thatās a more niche combo, so I would not be shocked if you found a bug/regression there.
So my honest read is:
- āIs this a feature of BOOT.md?ā ā yes
- āAre you using it wrong?ā ā probably no
- āCould this still be buggy?ā ā very possibly, yes
Docs:
Given your repro so far, I think youāve earned the right to be suspicious of the implementation, not your prompt š
looking at openclaw status --all. the "agents" section shows 2 agents, my main and a public one i tried to create. the main one has 146 sessions... is that right? should those be cleaned up?
Let me verify the session-cleanup behavior so I donāt hand-wave the wrong knob.
146 is not crazy, no.
A few reasons it can add up fast:
- daily resets create new sessions
- different threads/channels get different session keys
/newand/resetcreate more- test runs / experiments / public-vs-main agent separation
So 146 sessions on one agent is plausible, especially if youāve been poking at it a lot.
Should they be cleaned up?
Not urgently.
By default, OpenClawās session maintenance is bounded around:
pruneAfter: "30d"maxEntries: 500
and the default maintenance mode is usually warn, not enforce, so it may report but not auto-clean.
Safe way to check
openclaw sessions cleanup --dry-run
If the preview looks good:
openclaw sessions cleanup --enforce
And if you want it automatic:
{
session: {
maintenance: {
mode: "enforce",
pruneAfter: "30d",
maxEntries: 500
}
}
}
So short version:
- 146 sessions? fine
- must clean now? no
- worth previewing cleanup? yes
Docs:
okay. as for boot-md, i didn't see anything relevant to it at all in the command output
Yeah, thatās useful signal.
By itself, no boot-md output is ambiguous because success is quiet, but combined with:
- minimal BOOT test fails
- manual message test works
- hook is configured
- still nothing on restart
ā¦the strongest remaining suspect is:
the running gateway service is not actually loading the same config/runtime state youāre editing, or the startup hook never gets registered on boot.
Next exact thing Iād check
openclaw gateway status
What I care about in that output:
- which config path the service says itās using
- whether it thinks it is the expected service/runtime
- any hint about supervisor vs unmanaged process
If that config path is not the exact file you edited, I think weāve got it.
If you want, paste the openclaw gateway status output here and Iāll read it with you.
CLI and service are using the same config file, which is my main one. None others exist. nothing else of note
At this point, Iād stop blaming your setup.
I think youāve got a real bug / regression:
BOOT.mdexists in the correct workspaceboot-mdis enabled- CLI + service use the same config
- manual
messagetool send works - minimal BOOT startup send does not
- no meaningful
boot-mdactivity appears on restart
Thatās a pretty clean repro.
Iād file it here
Suggested repro summary
- OpenClaw version:
2026.4.15 BOOT.mdpresent in~/.openclaw/workspace/BOOT.mdhooks.internal.entries["boot-md"].enabled = trueopenclaw hooks info boot-mdshows ready- CLI and running service use the same config file
- manual message-tool DM works from the same agent
- minimal
BOOT.mdthat only sends a fixed DM on startup does not run / does not send - restart and full reboot show no useful
boot-mdoutput
Tiny minimal BOOT.md for the issue
On gateway startup, use the message tool exactly once to send a Discord DM to my user id saying:
"boot test"
After sending, reply with only NO_REPLY.
If sending fails, reply with only NO_REPLY.
Honestly, you did the right debugging here. This is solid.
If you want, I can help you write a crisp GitHub issue body before you post it.
I noticed some similar open issues
https://github.com/openclaw/openclaw/issues/67191
https://github.com/openclaw/openclaw/issues/50721
Let me sanity-check those two issues before I say āyep same bugā and accidentally mislead you.
Yep, I checked them, and those look very relevant.
- #67191 looks almost exactly like your case, especially the āBOOT.md runs silently / startup delivery doesnāt reach the userā angle.
- #50721 looks like the same class of bug, just seen on Telegram instead of Discord.
So, no, youāre probably not the only one hitting this.
And yes, it really does look like a real BOOT.md startup-delivery issue, not just you wiring it wrong.
What Iād do
I would not open a totally fresh issue yet.
Instead, Iād comment on #67191 with your extra repro details:
- OpenClaw version:
2026.4.15 - channel: Discord
BOOT.mdin the correct workspace
boot-mdenabled- CLI and service use the same config
- manual
messagetool send works - minimal
BOOT.mdstartup send fails - nothing useful appears in logs on restart
That strengthens the existing report without fragmenting it.
If you want, I can help you write a short comment for #67191 thatās clean and useful.
Done.
Nice, that was the right move.
If this thread helped you get to the root of it, please right-click the solution message ā Apps ā ā Mark Solution so Answer Overflow can index it for the next person.