Claude Code Claude Opus 4.6 commited on
Commit
ebe6433
·
1 Parent(s): 0c79ba5

Claude Code: Fix Cain error field handling - clear stale 'unknown' at startup

Browse files

- Update entrypoint.sh to clean ALL status file locations (not just /data)
- Update app.py to write consistent status to all possible locations
- Prevents 'unknown' errors from persisting across container restarts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Files changed (2) hide show
  1. app.py +29 -13
  2. entrypoint.sh +34 -16
app.py CHANGED
@@ -454,7 +454,7 @@ try:
454
  print(f">>> CAIN: Status file updated at {status_path}: stage=RUNNING_A2A_READY", flush=True)
455
 
456
  # Also write to brain_minimal's status file location for consistency
457
- # Try multiple possible locations with fallback
458
  _script_dir = Path(os.path.abspath(os.path.dirname(__file__)))
459
  _possible_status_paths = [
460
  Path("/app/openclaw/.openclaw/agents/cain_status.json"), # Nested structure (Docker)
@@ -462,22 +462,38 @@ try:
462
  _script_dir / "openclaw" / ".openclaw" / "agents" / "cain_status.json",
463
  _script_dir / ".openclaw" / "agents" / "cain_status.json",
464
  ]
465
- brain_status_path = None
466
  for p in _possible_status_paths:
467
- # Create parent directory if it doesn't exist
468
  try:
 
469
  p.parent.mkdir(parents=True, exist_ok=True)
470
- brain_status_path = p
471
- break
472
- except Exception:
473
- continue
474
- if brain_status_path:
475
- try:
476
- with open(brain_status_path, 'w') as f:
477
- json.dump(status_data, f, indent=2)
478
- print(f">>> CAIN: Brain status file also updated at {brain_status_path}", flush=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
479
  except Exception as e:
480
- print(f">>> CAIN WARNING: Could not write brain status file: {e}", flush=True)
481
  except Exception as e:
482
  print(f">>> CAIN WARNING: Could not update status file: {e}", flush=True)
483
 
 
454
  print(f">>> CAIN: Status file updated at {status_path}: stage=RUNNING_A2A_READY", flush=True)
455
 
456
  # Also write to brain_minimal's status file location for consistency
457
+ # CRITICAL: Write to ALL possible locations to ensure "unknown" errors are cleared everywhere
458
  _script_dir = Path(os.path.abspath(os.path.dirname(__file__)))
459
  _possible_status_paths = [
460
  Path("/app/openclaw/.openclaw/agents/cain_status.json"), # Nested structure (Docker)
 
462
  _script_dir / "openclaw" / ".openclaw" / "agents" / "cain_status.json",
463
  _script_dir / ".openclaw" / "agents" / "cain_status.json",
464
  ]
 
465
  for p in _possible_status_paths:
 
466
  try:
467
+ # Create parent directory if it doesn't exist
468
  p.parent.mkdir(parents=True, exist_ok=True)
469
+ # Check if file exists and has stale "unknown" error - clean it
470
+ if p.exists():
471
+ try:
472
+ with open(p, 'r') as f:
473
+ existing_data = json.load(f)
474
+ # Only overwrite if it has a stale "unknown" error
475
+ existing_error = existing_data.get('error')
476
+ if isinstance(existing_error, str) and existing_error.strip().lower() in ('unknown', 'none', 'null', ''):
477
+ with open(p, 'w') as f:
478
+ json.dump(status_data, f, indent=2)
479
+ print(f">>> CAIN: Cleaned stale error at {p}", flush=True)
480
+ # Also update if our status is newer
481
+ elif status_data.get('last_updated') > existing_data.get('last_updated', ''):
482
+ with open(p, 'w') as f:
483
+ json.dump(status_data, f, indent=2)
484
+ print(f">>> CAIN: Updated status at {p}", flush=True)
485
+ except json.JSONDecodeError:
486
+ # File exists but is corrupted - overwrite with clean data
487
+ with open(p, 'w') as f:
488
+ json.dump(status_data, f, indent=2)
489
+ print(f">>> CAIN: Fixed corrupted status file at {p}", flush=True)
490
+ else:
491
+ # File doesn't exist - create it with clean data
492
+ with open(p, 'w') as f:
493
+ json.dump(status_data, f, indent=2)
494
+ print(f">>> CAIN: Created new status file at {p}", flush=True)
495
  except Exception as e:
496
+ print(f">>> CAIN WARNING: Could not write to {p}: {e}", flush=True)
497
  except Exception as e:
498
  print(f">>> CAIN WARNING: Could not update status file: {e}", flush=True)
499
 
entrypoint.sh CHANGED
@@ -46,23 +46,41 @@ mkdir -p /data
46
 
47
  # CRITICAL: Clear stale error field from cain_status.json before startup
48
  # This prevents "unknown" errors from persisting across container restarts
49
- if [ -f "/data/cain_status.json" ]; then
50
- echo "Cleaning stale error field from status file..."
51
- # Use python to safely update JSON (sets error to null)
52
- python3 -c "
53
  import json
54
- try:
55
- with open('/data/cain_status.json', 'r') as f:
56
- data = json.load(f)
57
- data['error'] = None
58
- data['_cleaned_at'] = '$(date -u +"%Y-%m-%dT%H:%M:%SZ")'
59
- with open('/data/cain_status.json', 'w') as f:
60
- json.dump(data, f, indent=2)
61
- print('Status file error field cleared')
62
- except Exception as e:
63
- print(f'Could not clean status file: {e}')
64
- " 2>/dev/null || echo "(Could not clean status file - continuing)"
65
- fi
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
  echo ""
68
  echo "=========================================="
 
46
 
47
  # CRITICAL: Clear stale error field from cain_status.json before startup
48
  # This prevents "unknown" errors from persisting across container restarts
49
+ # Clean ALL possible status file locations to ensure consistency
50
+ echo "Cleaning stale error field from status files..."
51
+ python3 -c "
 
52
  import json
53
+ from pathlib import Path
54
+
55
+ status_files = [
56
+ Path('/data/cain_status.json'),
57
+ Path('/app/openclaw/.openclaw/agents/cain_status.json'),
58
+ Path('/app/.openclaw/agents/cain_status.json'),
59
+ ]
60
+
61
+ cleaned = 0
62
+ for status_file in status_files:
63
+ try:
64
+ if status_file.exists():
65
+ with open(status_file, 'r') as f:
66
+ data = json.load(f)
67
+ error = data.get('error')
68
+ # Fix: if error is string 'unknown' or contains 'unknown', set to null
69
+ if isinstance(error, str) and error.strip().lower() in ('unknown', 'none', 'null', ''):
70
+ data['error'] = None
71
+ data['_cleaned_at'] = '$(date -u +"%Y-%m-%dT%H:%M:%SZ")'
72
+ with open(status_file, 'w') as f:
73
+ json.dump(data, f, indent=2)
74
+ cleaned += 1
75
+ print(f' Cleaned: {status_file}')
76
+ elif error is None:
77
+ print(f' OK: {status_file} (error already null)')
78
+ except Exception as e:
79
+ print(f' Could not clean {status_file}: {e}')
80
+
81
+ print(f'Cleaned {cleaned} status file(s)')
82
+ " 2>/dev/null || echo "(Could not clean status files - continuing)"
83
+ echo ""
84
 
85
  echo ""
86
  echo "=========================================="