#Refreshing Context
1 messages · Page 1 of 1 (latest)
True
There isn’t a single “reload context for every active Discord session” button, because each Discord channel/thread is its own session key — but in practice you usually don’t need one.
1) AGENTS.md / SOUL.md / USER.md etc.
Those bootstrap files are injected on every run (i.e. whenever the bot processes a new message), so changes should take effect automatically the next time you send a message in that channel.
Best way to verify in any channel:
- send:
/context list
It will show:- which workspace that session is using
- which files are injected (and whether anything is truncated)
Docs: https://docs.openclaw.ai/concepts/context
If it’s clearly still using old instructions, 99% of the time it’s one of these:
- you edited the files in a different workspace than the agent/session is actually using (multi-agent routing often means multiple workspaces)
- the file is being truncated, and your changes are past the truncation point (
agents.defaults.bootstrapMaxChars)
2) MEMORY.md + memory/*.md changes (and “index force”)
openclaw memory index --force only affects semantic memory search (memory_search / memory_get). It does not “push” new info into every ongoing conversation automatically.
Also important for Discord specifically:
- Guild channels do not auto-load
MEMORY.mdby default (DMs do).
So in a server channel, your MEMORY.md edits won’t show up unless the agent callsmemory_search/memory_get, or you move the always-needed stuff into AGENTS.md / USER.md.
Docs (Discord memory behavior): https://docs.openclaw.ai/channels/discord (see “Plan for memory in guild channels”)
3) If you want existing channels to “forget the old vibe”
Even though bootstrap files refresh, the conversation history in each channel is still there, and it can “pull” the bot back toward prior assumptions.
Per channel/thread, do one of:
/new(fresh session, cleanest)/compact(keeps continuity but compresses old history)
4) Multiple active Discord channels
You’ll need to trigger a run in each channel you care about (e.g. /context list, then /new if needed). OpenClaw won’t proactively re-run every session just because files changed.
If you tell me whether you’re using multiple agents (routing) and what you see in /context list (workspace path + which files are injected), I can tell you exactly why a given channel isn’t picking up your edits.
Also: what version are you on? (openclaw --version)
Yep — multiple agents is the missing piece.
With multi-agent routing, “context files” are per-agent, because each agent has its own workspace (and its own memory index).
So if you edited AGENTS.md / SOUL.md / MEMORY.md in one workspace, only the channels routed to that agent will pick it up.
What to do
- Figure out which agent each Discord channel is actually using
In each channel/thread, run:
/context list(best)
It will show the Workspace: path and which files are injected.- or
/status(quick sanity)
- Apply your edits to the right workspaces
For every agent you care about, update the files in that agent’s workspace (or intentionally point multiple agents at the same workspace, if you really want shared persona/memory).
Docs (agents = isolated workspaces): https://docs.openclaw.ai/concepts/multi-agent
- Reindex memory for all agents (if that’s what you meant by “index force”)
Memory indexing is also per-agent. You can reindex them all from the gateway host with:
openclaw memory index --force
(or target one: openclaw memory index --agent <id> --force)
Docs: https://docs.openclaw.ai/cli/memory
- Make running sessions “pick it up”
- Bootstrap files (AGENTS/SOUL/etc.) are injected on the next run, so usually just sending a message is enough.
- If old chat history is fighting the new rules/persona, do
/newin that channel to start clean.
Extra Discord gotcha (memory)
In guild channels, MEMORY.md typically doesn’t auto-load (privacy). So even if you updated it, you may need the agent to use memory_search/memory_get, or move “always-needed” rules into AGENTS.md/USER.md.
Docs: https://docs.openclaw.ai/channels/discord (see “Plan for memory in guild channels”)
If you paste the /context list output from 1–2 of the channels that aren’t updating (just the “Workspace:” + “Injected workspace files” section), I can tell you exactly which agent/workspace you need to edit.
There is only one workspace, I'm pretty sure there is only one agent. this context looks the same for each of the discord channels and DM
Workspace: /home/akessel56/.openclaw/workspace
Bootstrap max/file: 20,000 chars
Bootstrap max/total: 150,000 chars
Sandbox: mode=off sandboxed=false
System prompt (estimate): 27,802 chars (~6,951 tok) (Project Context 15,205 chars (~3,802 tok))
Injected workspace files:
AGENTS.md: OK | raw 3,759 chars (~940 tok) | injected 3,759 chars (~940 tok),
SOUL.md: OK | raw 4,450 chars (~1,113 tok) | injected 4,450 chars (~1,113 tok),
TOOLS.md: OK | raw 880 chars (~220 tok) | injected 880 chars (~220 tok),
IDENTITY.md: OK | raw 487 chars (~122 tok) | injected 487 chars (~122 tok),
USER.md: OK | raw 1,263 chars (~316 tok) | injected 1,263 chars (~316 tok),
HEARTBEAT.md: OK | raw 138 chars (~35 tok) | injected 138 chars (~35 tok),
BOOTSTRAP.md: MISSING | raw 0 | injected 0,
MEMORY.md: OK | raw 3,531 chars (~883 tok) | injected 3,531 chars (~883 tok)
Skills: backup_status, stock-quotes, system_health, discord, gog, healthcheck, skill-creator, video-frames, weather
Tool list (system prompt text): 2,091 chars (~523 tok)
Tool schemas (JSON): 16,843 chars (~4,211 tok) (counts toward context; not shown as text)
Tools: read, edit, write, exec, process, cron, message, tts, gateway, sessions_list, sessions_history, sessions_send, sessions_spawn, subagents, session_status, web_search, web_fetch, memory_search, memory_get
Session tokens (cached): unknown / ctx=200000
Based on that /context list, you’re already in the “reloaded” state.
Key tells:
- It’s showing the current workspace path (
/home/akessel56/.openclaw/workspace) - All your bootstrap files show
raw == injected(so no truncation, and it’s pulling them in as-is) - The skills/tool list is being rebuilt into the system prompt estimate
So what do you actually need to do?
A) For AGENTS.md / SOUL.md / etc.
Nothing special. Those are injected every time the agent runs. There’s no separate “reload context” command.
If you want to prove a specific channel is seeing your latest edits, in that channel send something like:
B) For memory/*.md (the stuff you “indexed --force”)
Important nuance: openclaw memory index --force only affects what shows up via memory_search / memory_get.
Those memory/YYYY-MM-DD.md files are not auto-injected into every run (only MEMORY.md / memory.md are). So if the behavior you’re expecting depends on daily notes, you must either:
- ask the agent to use
memory_search, or - explicitly pull them with
memory_get.
A quick test is: in any channel, ask it:
- “Run
memory_searchfor<a phrase you know is in today’s memory file>and show me the top hits.”
C) If you want active sessions to stop “acting like before”
Even though bootstrap files refresh, the chat history in each channel still exists and can keep steering tone/assumptions.
Fix (per channel/thread):
/new(clean reset, recommended after big persona/rules changes)- or
/compact(keeps continuity but compresses older history)
I had noticed earlier today that after I did a /reset in the various channels, things changed a bit, so i guess that was more about the session being new, but this was event true for my hourly cron, so I just wasn't sure what was causing that behavior. The cron in particular which are all: "sessionTarget": "isolated". So I was surprised that things changed after /reset. So here is an example - i have a cron "hourly checkin" that does a few things and then messages a discord channel. It was returning: HEARTBEAT_OK, even though I had removed that from the cron (under your instructions) but it wasn't until I did the /reset that it dropped the HEARTBEAT_OK
[3:15 AM]
APP
Openclaw Bot: HEARTBEAT_OK
[4:15 AM]
APP
Openclaw Bot: HEARTBEAT_OK
[5:15 AM]
APP
Openclaw Bot: HEARTBEAT_OK
[6:15 AM]
APP
Openclaw Bot: HEARTBEAT_OK
[7:15 AM]
APP
Openclaw Bot: HEARTBEAT_OK
[8:15 AM]
APP
Openclaw Bot: Everything is running smoothly for the hourly check-in.
[9:15 AM]
APP
Openclaw Bot: The hourly check-in is complete, everything looks good.
[10:15 AM]
APP
Openclaw Bot: The hourly check-in is complete and everything is running as expected.
[11:15 AM]
APP
Openclaw Bot: The hourly check-in finished successfully.
[12:15 PM]
APP
Openclaw Bot: The hourly check-in is complete and everything is running normally.
[1:15 PM]
APP
Openclaw Bot: The hourly check-in is complete and everything is running as it should.
[2:15 PM]
APP
Openclaw Bot: The hourly check-in finished successfully.
[3:15 PM]
APP
Openclaw Bot: The hourly check-in is complete and everything is running normally.
What you’re describing (cron output changing right after you /reset a Discord channel) is a strong signal that something else changed at the same time — because an isolated cron job shouldn’t care about that channel’s session at all.
Per the cron docs, sessionTarget: "isolated" runs in cron:<jobId> and “each run starts a fresh session id (no prior conversation carry-over).”
Source: https://docs.openclaw.ai/automation/cron-jobs (“Isolated jobs” section)
So if it was still replying HEARTBEAT_OK after you changed the job, the most common causes are:
1) The cron job wasn’t actually running as “isolated” (or it’s a legacy/migrated shape)
If the job is sessionTarget: "main" (payload systemEvent), it runs via the heartbeat runner, and HEARTBEAT_OK is a totally normal “nothing to do” response.
Even if you think it’s isolated, verify what the gateway is actually executing.
2) You edited ~/.openclaw/cron/jobs.json while the Gateway was running
Cron jobs are loaded into memory and written back on changes. Manual edits are only safe when the gateway is stopped — otherwise you can end up thinking you changed the job, but the running gateway still has the old version.
“The Gateway loads the file into memory and writes it back on changes, so manual edits are only safe when the Gateway is stopped.”
Source: https://docs.openclaw.ai/automation/cron-jobs (“Where cron jobs are stored”)
That would explain why it “kept doing the old thing” for hours until some later event (often a gateway restart) made it pick up the new definition.
3) You changed the cron prompt, but the job was still using an old cached definition until a Gateway restart
/reset itself doesn’t reload cron job definitions, but people often do a “reset → tweak → restart” loop and the restart is the real turning point.
What I’d do to pin this down (fast)
A) Confirm what’s stored for that job right now
On the gateway host, open ~/.openclaw/cron/jobs.json and find your hourly checkin job entry. You’re looking for:
sessionTargetshould be"isolated"- payload should be
kind: "agentTurn" - the payload
messageshould match what you think you changed
(Just read it while running is fine — just don’t edit it live.)
B) Force a run and watch the run log
From the FAQ troubleshooting pattern:
openclaw cron run <jobId> --force
openclaw cron runs --id <jobId> --limit 50
Source: https://docs.openclaw.ai/help/faq (cron debug section)
C) If you did edit jobs.json manually: restart the gateway
That’s the clean way to ensure the in-memory job list matches disk:
openclaw gateway restart
If you paste the hourly checkin job’s JSON snippet (just that one job object — redact any tokens/targets), I can tell you immediately whether it’s truly isolated, and why HEARTBEAT_OK was still possible.
I'm on v2026.3.7 by the way:
The only thing i did new when the output changed was the /reset. The cron looks like how we changed it last night to a) take out any reference to "Heartbeat", b) add lightcontext:true: here is the cron:
"id": "a7630d6c-3973-4254-ad26-06c9ce9bd33b",
"agentId": "main",
"name": "Hourly Checkin",
"enabled": true,
"createdAtMs": 1770726897716,
"updatedAtMs": 1773357317229,
"schedule": {
"expr": "15 * * * *",
"kind": "cron"
},
"sessionTarget": "isolated",
"wakeMode": "now",
"payload": {
"kind": "agentTurn",
"message": "### [HOURLY: HEALTH CHECK] ###\nCheck the following:\n1. WordPress: 'web_fetch url=https://armgs.org'\n\nCRITICAL ERROR PROTOCOL:\nIf any tool call fails, command is not found, or checks cannot be completed successfully, trigger 'message' tool: action=send, channel=discord, target=11111111111111111111, message=\\\"HOURLY_FAIL: [Short Error Reason]\\\", then output: HOURLY_FAIL: [Short Error Reason] and stop.\n\nOtherwise, if all checks succeed:\n- Use the 'write' tool to overwrite 'memory/hourly-state.txt' with EXACTLY: \\\"YYYY-MM-DDTHH:MM:SS [TZ]\\\"\n- Output exactly: HOURLY_OK\n- Stop.\n\nFORGET all previous summary formats. Do not output any other phrases under any circumstances. If all is healthy, ONLY output \\\"HOURLY_OK\\\" (one line, nothing else). Do not add any extra commentary, tool calls, or internal summary tags. Use lightContext.",
"model": "31lite",
"lightContext": true
},
"delivery": {
"mode": "announce",
"channel": "discord",
"to": "11111111111111111111"
},
"state": {
"nextRunAtMs": 1773360900000,
"lastRunAtMs": 1773357300041,
"lastStatus": "ok",
"lastDurationMs": 17188,
"consecutiveErrors": 0,
"lastRunStatus": "ok",
"lastDeliveryStatus": "delivered",
"lastDelivered": true
}
},
@sleek wind Where did you go?
Short answer: there’s no single “reload everything for all sessions” button — workspace files (AGENTS.md, SOUL.md, USER.md, MEMORY.md) are injected on every run and memory indexing is per-agent — but cron runs and existing session history behave differently, so you need to handle each case slightly differently. Below are why you saw the /reset effect and exactly what to do to make cron output deterministic and to ensure all channels pick up your edits.
Why /reset changed the output
- /reset clears the session history for that channel/session. That will cause the next run in that session to be built from the fresh system prompt (so any injected bootstrap files you changed are used from scratch). That explains why you saw the behavior change immediately after /reset.
- Isolated cron jobs run in session cron:<jobId> and start a fresh session each run. However you are using lightContext:true, which intentionally runs with an empty bootstrap context — so changes to AGENTS.md / SOUL.md will not affect the isolated cron run when lightContext is true.
- The server contains logic that suppresses trivial heartbeat-only payloads (HEARTBEAT_OK) from being posted to users (fix in 2026.3.7). If you still see HEARTBEAT_OK noise, either older runs (before the fix) or a delivery/main-session summary fallback path produced the message — we can confirm by inspecting the run logs.
What to check now (quick diagnostics)
-
Inspect the last cron runs (see what the isolated run actually produced):
openclaw cron runs --id a7630d6c-3973-4254-ad26-06c9ce9bd33b --limit 10 --json -
Tail the JSONL run log to see full payloads:
tail -n 200 ~/.openclaw/cron/runs/a7630d6c-3973-4254-ad26-06c9ce9bd33b.jsonl -
Confirm delivery / summary flags for the last run (shows if announce delivered or main session got a summary):
(the output of step 1 includes summary, outputText, delivered, deliveryAttempted)
How to make cron output deterministic (recommended)
If you want a guaranteed exact line "HOURLY_OK" (or HOURLY_FAIL) every time, do one of these robust options:
A — Let the agent send the final message itself, then disable cron announce
-
Edit job to disable announce delivery (so cron won't try to synthesize/announce a summary):
openclaw cron edit <jobId> --no-deliver -
Change the job payload message to instruct the assistant to call the message tool for the final send. Example wording for the payload (put into cron
message):Check the system. If any check fails:
- call the message tool: action=send, channel=discord, target=11111111111111111111, message="HOURLY_FAIL: [Short Error Reason]"
- output exactly: HOURLY_FAIL: [Short Error Reason]
- stop
Otherwise: - write memory/hourly-state.txt with EXACTLY: "YYYY-MM-DDTHH:MM:SS [TZ]"
- call the message tool: action=send, channel=discord, target=11111111111111111111, message="HOURLY_OK"
- stop
Why this is robust: the message tool send is authoritative (the run sets finalRunResult.didSendViaMessagingTool=true) and the cron delivery dispatcher will skip duplicate announce when it sees the run already sent the message.
B — (If you want cron announce) Make the final assistant output be the exact token and use a reliable model
- Ensure the assistant’s last assistant payload is EXACTLY "HOURLY_OK" on its own line and that no tool wrappers or extra narration appear afterwards.
- Use a stronger, instruction-following model for the job (31lite is low-cost/less reliable). Lower-tier models can add stray commentary; higher-quality models follow strict output rules more reliably.
- Keep lightContext=false if you need workspace bootstrap context to be injected for the run.
If you prefer I can draft the exact payload string (properly quoted for the CLI) to put into your cron job.
If you need to force ALL Discord sessions to behave as-if-new
- Manual (safe): send
/newin each channel you want cleared. That restarts that session and forces fresh injection. - Aggressive (destructive): prune session stores (deletes transcripts). Use with care:
openclaw sessions cleanup --agent main --enforce
(or--all-agents --enforce) — this removes/rewrites stored sessions and will make those conversations start fresh. Only use if you’re OK losing stored transcripts.
If you edited cron jobs manually in jobs.json
- Manual edits only reliably take effect when the gateway is stopped. If you edited jobs.json by hand while the gateway was running you may have an in-memory/ on-disk mismatch — restart the gateway:
openclaw gateway restart
Other helpful checks / tips
- Because you’re on v2026.3.7, the HEARTBEAT_OK suppression fix is present (#32093). If you still see HEARTBEAT_OK appearing as a user-facing summary, check the run logs (steps above) to see whether the run actually produced something else, or whether announce/delivery failed and the main-session fallback enqueued a summary.
- To examine which workspace/context a session is using in a channel, run
/context listin that channel (you already did that; it showed the workspace path). - If you want me to review one of the problematic run JSON lines, paste the last run entry from ~/.openclaw/cron/runs/<jobId>.jsonl (redact channel IDs if you want) and I’ll point out why it produced the English text instead of HOURLY_OK.
Summing up (recommended short action)
- Run: openclaw cron runs --id <jobId> --limit 10 --json (paste the last run here if you want review).
- If you want guaranteed EXACT outputs, change the job to --no-deliver and instruct the assistant to call the message tool for HOURLY_OK / HOURLY_FAIL.
- If you want all Discord sessions to use new AGENTS/SOUL immediately,
/neweach channel (or use sessions cleanup if you accept transcript deletion).
Tell me which you want to do (inspect run logs, I can craft the "message-tool" cron payload text, or help with a safe cleanup script to reset sessions), and I’ll give exact commands/JSON to apply.
I think you explain the difficulty clearly. One thing that is a surprise to me is that having lightContext=false , results in those .md files not being loaded, so that shouldn't be used except for very simple crons.
Yep — and just to untangle the wording:
lightContext: true(for isolatedagentTurncrons) means “lightweight bootstrap” → the run does not inject your workspace bootstrap files (AGENTS.md,SOUL.md,USER.md,MEMORY.md, etc.). For cron runs, it’s essentially empty bootstrap on purpose.lightContext: false(or omitted) means normal behavior → those.mdfiles are injected each turn.
Docs (emphasis mine):
“Isolated jobs (
agentTurn) can setlightContext: true… keeps cron bootstrap context empty on purpose.”
Source: https://docs.openclaw.ai/automation/cron-jobs#lightweight-bootstrap-context
So your conclusion is right, but the switch is the other way around: use lightContext: true only when the cron message itself contains all the rules it needs and you’re optimizing for token/cost, and keep it off when you want the job to inherit your normal “brain” (AGENTS/SOUL/MEMORY).
One extra nuance: even with normal context, memory/*.md daily files are never auto-injected (those are only pulled via memory_search / memory_get). The file that would be injected is MEMORY.md (when not in lightContext).
got it! thanks