# Cron provider/auth troubleshooting

Use this when a Hermes cron job fails with an LLM/provider RuntimeError while any script phase appears otherwise healthy.

## Pattern observed

- Script-backed morning briefing job failed with:
  - `RuntimeError: Error code: 401 - {'error': {'message': 'User not found.', 'code': 401}}`
- Job definition showed:
  - `provider: openrouter`
  - `model: openrouter/auto`
- `~/.hermes/auth.json` showed OpenRouter credential status as exhausted/invalid with the same `401 User not found` error.
- Prior output files showed the script had succeeded on earlier days, so the failure was not inherently a script or Telegram delivery problem.

## Diagnosis workflow

1. List jobs and identify the failing job:
   ```bash
   hermes cron list
   ```
2. Inspect the job definition and latest output:
   ```bash
   python3 - <<'PY'
   from pathlib import Path
   job='JOB_ID'
   p=Path.home()/'.hermes/cron/output'/job
   for f in sorted(p.glob('*.md'), key=lambda x:x.stat().st_mtime, reverse=True)[:3]:
       print('\n==', f, '==')
       print('\n'.join(f.read_text(errors='replace').splitlines()[-40:]))
   PY
   ```
3. Inspect provider status without printing secrets:
   ```bash
   python3 - <<'PY'
   import json
   from pathlib import Path
   p=Path.home()/'.hermes/auth.json'
   data=json.loads(p.read_text())
   for provider, value in data.items():
       print(provider, {k:v for k,v in value.items() if 'key' not in k.lower() and 'token' not in k.lower()})
   PY
   ```
4. If the provider is invalid/exhausted, update only the affected job to a known-good provider/model, rather than rewriting the script.

## Minimal remediation example

```bash
hermes cron edit JOB_ID
# or use the cronjob tool update action if available:
# provider: openai-codex
# model: gpt-5.5
```

Then trigger and verify:

```bash
hermes cron run JOB_ID --accept-hooks
sleep 75
hermes cron list
```

Success criterion: the job shows a fresh `Last run: ... ok` and the next scheduled run is back to the normal schedule.

## Pitfalls

- `hermes cron run JOB_ID` schedules execution on the next scheduler tick; it does not necessarily run synchronously before the command returns.
- Check `hermes cron status` if the next-run timestamp is already in the past; the gateway scheduler must be running.
- Do not paste `.env` or credential values into chat/logs. Report only provider name, status, and error code/message.
