[Bug]: v1.0.169 can enter an infinite compaction loop and exhaust Claude Code token quota
Author: wukakaCreated Sep 17, 2026Updated Sep 17, 2026
Labelsbug
Platform
Claude Code
context-mode version
v1.0.169
Debug script output (REQUIRED)
{
"version": "2.0.0",
"generated": "2026-09-17T09:02:49Z",
"sections": {
"1. System Info": {
"checks": [],
"info": {
"OS type": "macos",
"uname -a": "Darwin Mac-mini.local 23.6.0 Darwin Kernel Version 23.6.0: Wed Jul 31 20:48:44 PDT 2024; root:xnu-10063.141.1.700.5~1/RELEASE_X86_64 x86_64",
"Architecture": "x86_64",
"macOS version": "14.7 (23H124)",
"Shell": "/bin/zsh",
"Bash version": "3.2.57(1)-release",
"Locale": "LANG=zh_CN.UTF-8, LC_ALL=unset"
},
"configs": [],
"warnings": [],
"details": []
},
"2. Runtime Versions": {
"checks": [],
"info": {
"Node.js": "v24.15.0",
"node path": "/usr/local/opt/node@24/bin/node",
"execPath": "/usr/local/Cellar/node@24/24.15.0/bin/node",
"Node install method": "unknown",
"Bun": "1.3.14",
"bun path": "/Users/apple/.bun/bin/bun",
"Python": "Python 3.9.6",
"Ruby": "ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.x86_64-darwin23]",
"npm": "11.12.1",
"npm global root": "/usr/local/lib/node_modules"
},
"configs": [],
"warnings": [],
"details": []
},
"3. context-mode Installation": {
"checks": [
{
"pass": false,
"label": "build/ directory exists"
},
{
"pass": true,
"label": "hooks/pretooluse.mjs exists"
},
{
"pass": true,
"label": "hooks/sessionstart.mjs exists"
},
{
"pass": true,
"label": "server.bundle.mjs exists"
},
{
"pass": true,
"label": "cli.bundle.mjs exists"
}
],
"info": {
"Installed version": "1.0.169",
"Plugin root": "~/.claude/plugins/marketplaces/context-mode",
"Install method": "marketplace",
"npm latest": "1.0.169"
},
"configs": [],
"warnings": [],
"details": []
},
"4. better-sqlite3 Native Module": {
"checks": [
{
"pass": false,
"label": "better-sqlite3 .node binary exists"
},
{
"pass": false,
"label": "require('better-sqlite3') succeeds"
},
{
"pass": true,
"label": "npm ignore-scripts is false"
}
],
"info": {
"Node ABI version": "137"
},
"configs": [],
"warnings": [],
"details": []
},
"5. Adapter Detection": {
"checks": [],
"info": {
"Active adapter (env)": "none",
"Installed adapters": "claude-code cursor"
},
"configs": [],
"warnings": [],
"details": []
},
"6. Config Files": {
"checks": [],
"info": {
"Claude settings.json": "~/.claude/settings.json (exists)",
"Claude settings.local.json": "~/.claude/settings.local.json (exists)",
"Gemini settings.json": "~/.gemini/settings.json (not found)",
"Codex config.toml": "~/.codex/config.toml (not found)",
"Codex hooks.json": "~/.codex/hooks.json (not found)",
"Cursor hooks.json (project)": "~/.claude/plugins/marketplaces/context-mode/.cursor/hooks.json (not found)",
"Cursor mcp.json (project)": "~/.claude/plugins/marketplaces/context-mode/.cursor/mcp.json (not found)",
"Cursor mcp.json (global)": "~/.cursor/mcp.json (not found)",
"Cursor hooks.json (global)": "~/.cursor/hooks.json (not found)",
"VS Code mcp.json (project)": "~/.claude/plugins/marketplaces/context-mode/.vscode/mcp.json (not found)",
"opencode.json (project)": "~/.claude/plugins/marketplaces/context-mode/opencode.json (not found)",
"opencode.json (dotdir)": "~/.claude/plugins/marketplaces/context-mode/.opencode/opencode.json (not found)",
"opencode.json (global)": "~/.config/opencode/opencode.json (not found)",
"KiloCode settings.json": "~/.config/kilo/settings.json (not found)",
"OpenClaw openclaw.json": "~/.openclaw/openclaw.json (not found)",
"Kiro mcp.json": "~/.kiro/settings/mcp.json (not found)",
"Kiro default agent": "~/.kiro/agents/default.json (not found)",
"Zed settings.json": "~/.config/zed/settings.json (not found)"
},
"configs": [
{
"name": "Claude settings.json",
"path": "~/.claude/settings.json",
"exists": true,
"content": "{\n \"env\": {\n \"CLAUDE_CODE_DISABLE_AUTO_MEMORY\": \"1\",\n \"DISABLE_AUTOUPDATER\": \"1\"\n },\n \"permissions\": {\n \"allow\": [\n \"Bash(conda env *)\",\n \"Bash(pyenv versions *)\",\n \"Bash(conda --version)\",\n \"Read(//Users/apple/anaconda3/**)\",\n \"Read(//Users/apple/miniconda3/**)\",\n \"Read(//Users/apple/.conda/**)\",\n \"Bash(ls -la ~/work-zone/PY_ENV 2>&1)\",\n \"Read(//Users/apple/work-zone/PY_ENV/**)\",\n \"Bash(~/work-zone/PY_ENV/sample-crawler/bin/python3 demo_tks_b_hotel_list.py)\",\n \"Bash(cp demo_tks_b_hotel_list.py /tmp/test_pageindex1.py)\",\n \"Bash(python3 -)\",\n \"Read(//tmp/**)\",\n \"Bash(cp demo_tks_b_hotel_list.py /tmp/_test_p1.py)\",\n \"Bash(~/work-zone/PY_ENV/sample-crawler/bin/python3 /tmp/_test_p1.py)\",\n \"Bash(rm -f /tmp/_test_p1.py /tmp/test_pageindex1.py)\",\n \"Bash(python3 -c ' *)\",\n \"Bash(grep -nE 'native code|Function.prototype.*toString|\\\\\\\\$toString|myFunction_toString_symbol|delete Function' token-1006.js)\",\n \"Bash(python3.12 -c \\\"import pydantic, sqlalchemy; print\\\\('3.12 deps ok'\\\\)\\\")\",\n \"Bash(python3.10 -c \\\"import pydantic, sqlalchemy; print\\\\('3.10 deps ok'\\\\)\\\")\",\n \"Bash(sed -n '255,320b' core/db/redis/redis_helpers.py 2>/dev/null; echo \\\"=== setnx & expire helpers ===\\\"; grep -nE \\\"def \\\\(setnx|set_with_ttl|expire|set|delete|eval|register_script|pexpire\\\\)\\\\\\\\b\\\" core/db/redis/redis_helpers.py; echo \\\"=== circuit_breaker lock usage ===\\\"; sed -n '210,245p' core/flow_bus/circuit_breaker.py)\",\n \"Bash(echo \\\"---EXIT:$?---\\\")\",\n \"Bash(grep -nA2 -E \\\"def \\\\(hget|hset|hgetall|hdel|hmset|hincrby|sadd|srem|smembers\\\\)\\\\\\\\b\\\" core/db/redis/redis_helpers.py)\",\n \"Read(//Users/apple/Library/Python/3.9/lib/python/site-packages/redis/**)\",\n \"Bash(wc -c /Users/apple/Downloads/getHotelCommentInfo.json; echo \\\"---\\\"; ls /Users/apple/work-zone/shuyixin/ota-public-crawler/apps/xiecheng/spiders/)\",\n \"Read(//Users/apple/Downloads/**)\",\n \"Bash(cd /Users/apple/work-zone/shuyixin/ota-public-crawler; mkdir -p docs/superpowers/specs; echo \\\"=== get_wrapper signature ===\\\"; sed -n '52,70p' core/utils/requests_wrapper.py)\",\n \"Read(//Users/apple/work-zone/shuyixin/ota-public-crawler/**)\",\n \"Bash(docker build *)\",\n \"Bash(docker rmi *)\",\n \"Bash(docker compose *)\",\n \"Bash(git add *)\",\n \"Bash(git commit -m ' *)\",\n \"Bash(chmod +x /Users/apple/work-zone/shuyixin/syx-crawler-gateway/deploy.sh)\",\n \"Bash(bash -n /Users/apple/work-zone/shuyixin/syx-crawler-gateway/deploy.sh)\",\n \"Bash(sed -E 's/replicas: \\\\([2-9]|[0-9]{2,}\\\\)/replicas: 1/g' docker-stack.yml)\",\n \"Bash(docker network *)\",\n \"Bash(chmod +x /Users/apple/work-zone/shuyixin/syx-crawler-gateway/package.sh)\",\n \"Bash(bash -n package.sh)\",\n \"Bash(tar -czf /tmp/test-package.tar.gz docker-stack.yml docker-compose.yml nginx.conf deploy.sh)\",\n \"Bash(tar -tzf /tmp/test-package.tar.gz)\",\n \"Bash(chmod +x /Users/apple/work-zone/s"
},
{
"name": "Claude settings.local.json",
"path": "~/.claude/settings.local.json",
"exists": true,
"content": "{\n \"permissions\": {\n \"allow\": [\n \"Bash(mysqldump --version)\",\n \"mcp__plugin_context-mode_context-mode__ctx_batch_execute\",\n \"Bash(nc -z -v -w 5 10.8.15.251 19306)\",\n \"Bash(ping -c 2 -t 3 10.8.15.251)\",\n \"Bash(mysql -h 10.8.15.252 -P 19306 -u root '-pqNUyla7lvzP7GxgEqw6Hbu9F$FxsaiHj' --default-character-set=utf8mb4 -N -e 'SELECT COUNT\\\\(*\\\\) AS rows_now FROM spider_data.tb_hotel_price_range_room_info; SHOW PROCESSLIST;')\",\n \"Bash(ps -Ao pid,ppid,stat,etime,%cpu,%mem,command)\",\n \"Bash(ps -Ao pid,ppid,stat,etime,%cpu,command)\",\n \"Bash(kill 73646)\",\n \"Bash(kill 68352)\",\n \"Bash(ps -Ao pid,stat,command)\",\n \"Bash(kill 95324 95875)\"\n ]\n }\n}\n"
}
],
"warnings": [],
"details": []
},
"7. Hook Validation": {
"checks": [
{
"pass": true,
"label": "No stale hook paths in Claude settings.json"
},
{
"pass": true,
"label": "PreToolUse registered"
},
{
"pass": true,
"label": "PostToolUse registered"
},
{
"pass": true,
"label": "PreCompact registered"
},
{
"pass": true,
"label": "SessionStart registered"
}
],
"info": {},
"configs": [],
"warnings": [],
"details": []
},
"8. SQLite / FTS5 Test": {
"checks": [
{
"pass": false,
"label": "FTS5 in-memory test"
}
],
"info": {},
"configs": [],
"warnings": [],
"details": []
},
"9. Executor Test": {
"checks": [
{
"pass": true,
"label": "node subprocess spawn"
},
{
"pass": true,
"label": "bash subprocess spawn"
}
],
"info": {},
"configs": [],
"warnings": [],
"details": []
},
"10. Process Check": {
"checks": [],
"info": {
"Running context-mode processes": "2"
},
"configs": [],
"warnings": [],
"details": []
},
"11. Session Databases": {
"checks": [],
"info": {
"~/.claude/context-mode/sessions": "26 files, 13M",
"Total session DBs": "26"
},
"configs": [],
"warnings": [],
"details": []
},
"12. Environment Variables": {
"checks": [],
"info": {
"TMPDIR": "/var/folders/b_/4yjwb09d2gbf6h6yt5b94pd80000gn/T/",
"TEMP": "unset",
"TMP": "unset",
"NODE_OPTIONS": "unset",
"NODE_PATH": "/Users/apple/.claude/plugins/marketplaces/context-mode/node_modules:",
"NODE_EXTRA_CA_CERTS": "unset",
"SSL_CERT_FILE": "unset",
"CURL_CA_BUNDLE": "unset",
"SSH_AUTH_SOCK": "yes (set)",
"CONTEXT_MODE_SESSION_SUFFIX": "unset",
"CONTEXT_MODE_NODE": "unset"
},
"configs": [],
"warnings": [],
"details": []
},
"13. Hook Execution": {
"checks": [
{
"pass": false,
"label": "PreToolUse denies WebFetch"
},
{
"pass": true,
"label": "PreToolUse passes Write tool through"
},
{
"pass": false,
"label": "SessionStart injects routing context"
}
],
"info": {},
"configs": [],
"warnings": [],
"details": []
},
"14. MCP Server Startup": {
"checks": [
{
"pass": false,
"label": "Server entry + deps resolve"
}
],
"info": {},
"configs": [],
"warnings": [],
"details": []
},
"15. SQLite Concurrency": {
"checks": [
{
"pass": false,
"label": "Session DB uses WAL mode"
},
{
"pass": true,
"label": "No oversized WAL journals (>1MB)"
},
{
"pass": true,
"label": "No orphaned -shm files"
},
{
"pass": false,
"label": "Concurrent SQLite writes (3 conns × 30)"
}
],
"info": {},
"configs": [],
"warnings": [],
"details": []
},
"17. Sandbox Environment": {
"checks": [
{
"pass": true,
"label": "System CA certificates found"
},
{
"pass": true,
"label": "Temp dir writable"
},
{
"pass": true,
"label": "Env denylist strips dangerous vars"
}
],
"info": {
"Effective temp dir": "/var/folders/b_/4yjwb09d2gbf6h6yt5b94pd80000gn/T/"
},
"configs": [],
"warnings": [],
"details": []
},
"18. Network / TLS": {
"checks": [
{
"pass": true,
"label": "HTTPS to npm registry"
},
{
"pass": true,
"label": "Temp dir >100MB free"
}
],
"info": {},
"configs": [],
"warnings": [],
"details": []
}
},
"summary": {
"pass": 20,
"fail": 9,
"warnings": 0,
"total": 29
}
}Exact prompt that triggered the bug (REQUIRED)
auto compactFull error output (REQUIRED)
### Environment
* context-mode: `v1.0.169`
* Claude Code: `2.1.143`
* OS: `macOS 14.7 (23H124)`
* Installation: Claude Code plugin
* Node.js: `v24.15.0`
### Description
After upgrading context-mode from `v1.0.146` to `v1.0.169`, Claude Code can enter a continuous context compaction loop.
The session repeatedly triggers context compaction without making meaningful progress. The repeated compaction continues until the Claude token quota is exhausted.
Rolling back to `v1.0.146` stops the problem in the same workflow/environment.
### Observed behavior
The behavior looks approximately like:
Context reaches compaction threshold
↓
PreCompact hook
↓
context-mode saves/restores session state
↓
Claude Code compaction
↓
SessionStart hook
↓
context-mode restores/injects session state
↓
Context becomes large again
↓
Compaction is triggered again
↓
PreCompact
↓
SessionStart
↓
...
The important point is that this is not a single failed compaction. It becomes a repeated compaction/recovery cycle.
### Impact
This is severe because every iteration consumes Claude Code model usage.
In my case, the loop continued until the available Claude token quota was exhausted.
This makes the affected version effectively unusable for long-running Claude Code sessions.
### Regression
The same workflow was working with:
context-mode v1.0.146
After upgrading to:
context-mode v1.0.169
the continuous compaction behavior appeared.
Downgrading back to `v1.0.146` resolves the issue.
### Expected behavior
After a compaction:
1. `PreCompact` should persist the required session state.
2. Claude Code should compact the conversation.
3. `SessionStart` should restore only the necessary state.
4. The restored state should not immediately cause another compaction.
5. The session should continue normally.
There should be some form of guard against recursive/re-entrant compaction or repeated restoration causing another compaction cycle.
### Actual behavior
The compaction/recovery process can repeatedly re-enter itself, resulting in:
PreCompact → Compact → SessionStart → Compact → SessionStart → ...
and eventually exhausting the model usage quota.
### Additional information
I can provide the following if useful:
* Claude Code debug logs around the first compaction
* `PreCompact` / `SessionStart` hook output
* context-mode diagnostic output
* exact Claude Code version
* Node.js version
* comparison between v1.0.146 and v1.0.169
I have currently rolled back to `v1.0.146` because `v1.0.169` can consume the entire model quota through the compaction loop.Steps to reproduce (REQUIRED)
no step
What have you tried to fix it?
no
Pre-submission checklist
- I have run the debug script and pasted the output above
- I am using the latest version of context-mode
- I have searched existing issues for duplicates
- I have included steps to reproduce the issue
Operating System
macOS (Apple Silicon)
JS Runtime
v24.15.0
Source: mksglu/context-mode