Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 23 additions & 21 deletions claude-code/hooks/unbound.py
Original file line number Diff line number Diff line change
Expand Up @@ -919,34 +919,36 @@ def _resolve_claude_code_session_connector(server_uuid: str) -> Optional[tuple]:
if not _is_uuid(server_uuid):
return None
try:
files = []
latest = None
latest_ts = -1.0
for base in _claude_session_dirs():
if not base or not base.exists():
continue
try:
files.extend(base.glob('**/local_*.json'))
candidates = base.glob('*/*/local_*.json')
except Exception:
continue
if not files:
for f in candidates:
ts = _session_file_created_at(f)
if ts > latest_ts:
latest_ts, latest = ts, f
if latest is None:
return None
Comment on lines +935 to 936

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 No log entry when no session files are found

When latest is None (either because the session directories are empty or because no */*/local_*.json files matched), the function returns None silently. With the fixed-depth glob replacing the old **/ recursive glob, a depth mismatch — e.g., a future Claude version that nests files one level deeper — would produce exactly this silent None on every call, giving no indication in logs that the glob pattern is the problem.


files.sort(key=_session_file_created_at, reverse=True)
for f in files:
try:
data = json.loads(f.read_text(encoding='utf-8'))
except Exception:
continue
for entry in (data.get('remoteMcpServersConfig') or []):
if isinstance(entry, dict) and (entry.get('uuid') or '').lower() == server_uuid.lower():
name = entry.get('name')
if not name:
continue
cfg = {"additional_data": {"scope": "claude-connector"}}
url = entry.get('url')
if url:
cfg["url"] = url
cfg["type"] = "http"
return (name, cfg)
try:
data = json.loads(latest.read_text(encoding='utf-8'))
except Exception:
return None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newest session read failure

Medium Severity

After picking the newest local_*.json, any I/O or JSON parse error on that file makes _resolve_claude_code_session_connector return None immediately. The prior implementation skipped bad files and kept searching older session snapshots, so a transient corrupt or half-written newest file can leave MCP calls on a raw UUID with no policy even when older files still resolve the connector.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 76188fe. Configure here.

Comment thread
zeus-12 marked this conversation as resolved.
for entry in (data.get('remoteMcpServersConfig') or []):
if isinstance(entry, dict) and (entry.get('uuid') or '').lower() == server_uuid.lower():
name = entry.get('name')
if not name:
continue
cfg = {"additional_data": {"scope": "claude-connector"}}
url = entry.get('url')
if url:
cfg["url"] = url
cfg["type"] = "http"
return (name, cfg)
return None
except Exception as exc:
log_error(f"mcp cc-session resolve error: {server_uuid}: {exc}", 'mcp_connector')
Expand Down