Troubleshooting

简体中文

Start with the monitor’s own endpoints before changing CPA or auth files.

For a first pass that does not start the dashboard, run:

codex-quota-monitor print-config
codex-quota-monitor doctor

doctor reports which config file was loaded, whether the listen port is bindable, and whether the SQLite state path is writable. Use codex-quota-monitor init --mode user to regenerate a clean starter config when the local service wiring is unclear. After a Python install, cqm can replace codex-quota-monitor in these interactive commands.

1. Is The Monitor Running?

curl -fsS http://127.0.0.1:4515/healthz

Expected output:

{"ok":true}

If this fails, check the process or service manager first:

/healthz only means the monitor process is alive. It does not prove that CPA, the management key, auth files, SQLite history, or benchmark imports are healthy.

2. Where Are Logs?

The monitor follows a Unix service model:

Do not scrape stderr as a stable API. Use /api/v1/status, /api/v1/diagnostics, /api/v1/alerts, /api/v1/recommendations, /metrics, or the configured SQLite history database for machine-readable state. codex-quota-benchmark is the exception that writes experiment artifacts under its output directory, including temporary gateway stdout/stderr when requested.

3. Is CPA Reachable?

curl -fsS http://127.0.0.1:4515/api/v1/diagnostics | jq '.'

The Diagnostics tab and /api/v1/diagnostics separate:

If the Docker container cannot reach host CPA, use host.docker.internal as the CPA host and, on Linux Docker, add:

--add-host=host.docker.internal:host-gateway

4. Does The Management Key Work?

CPA management endpoints normally require a management key, including localhost requests. Pass it with --management-key-file /path/to/management-key, or with CODEX_QUOTA_MONITOR_MANAGEMENT_KEY_FILE for service and Docker deployments. For a bare CPA endpoint, the file must contain the same plaintext value as CPA remote-management.secret-key.

5. Why Are Quotas Unknown?

Unknown quota values usually mean direct Codex quota sampling is unavailable:

Check:

curl -fsS http://127.0.0.1:4515/api/v1/status | jq '.tabs.diagnostics'
curl -fsS http://127.0.0.1:4515/api/v1/alerts | jq '.'

If Diagnostics says the direct quota response shape changed, share only a redacted diagnostics/alerts payload and the package version. Do not share raw auth files or direct provider responses that may contain credential material.

6. Why Is The Pool Capacity Lower Than Raw 5h?

By default, total 5h capacity is capped by weekly remaining * 6.0. This avoids overstating short-window capacity when weekly quota is nearly exhausted.

Override it with:

codex-quota-monitor --weekly-to-five-hour-multiplier 8.0

Disable it with:

codex-quota-monitor --weekly-to-five-hour-multiplier off

Trends and Audit require a writable SQLite state database.

Check the Diagnostics tab for SQLite write errors.

State lifecycle basics:

# Back up
cp /var/lib/codex-quota-monitor/history.sqlite3 /var/lib/codex-quota-monitor/history.sqlite3.bak

# Clear history by stopping the service and removing the DB
systemctl stop codex-quota-monitor
rm /var/lib/codex-quota-monitor/history.sqlite3
systemctl start codex-quota-monitor

Adjust the path for rootless services (~/.local/state/codex-quota-monitor/history.sqlite3) or Docker (/data/history.sqlite3 inside the container volume). The monitor recreates the DB on the next successful write.

8. Why Does The Dashboard Periodically Use CPU?

The browser polls /api/v1/status. Cached responses are cheap, but when refreshSeconds expires the monitor refreshes CPA management data, optional direct quota samples, the dashboard snapshot, and SQLite-backed Trends/Stats summaries. Keep refreshSeconds long enough for your host; 15s is responsive but can be noisy on thermally constrained laptops when the CPA pool is large.

SQLite history is retained by historyRetentionDays, and deleted pages can stay inside the database file as SQLite freelist pages. That is file-size pressure, not active history rows. The service does not run VACUUM in the request path because it can block the monitor. If the file has grown too large, back it up, stop the service, and run maintenance manually:

systemctl stop codex-quota-monitor
cp /var/lib/codex-quota-monitor/history.sqlite3 /var/lib/codex-quota-monitor/history.sqlite3.bak
sqlite3 /var/lib/codex-quota-monitor/history.sqlite3 'PRAGMA freelist_count; VACUUM;'
systemctl start codex-quota-monitor

If you do not need Trends, ETA, Audit, Stats history, or native history backup, run without --state-db to disable SQLite history. That reduces local work but also removes the historical dashboard features.

9. What Is Safe To Share?

Do not share auth files, CPA admin keys, API keys, private gateway URLs, or full logs that contain them. It is usually safe to share:

Use codex-quota-monitor redact to create copies for sharing:

codex-quota-monitor redact /tmp/cqm-diagnostics.json --output /tmp/cqm-diagnostics-redacted.json
codex-quota-monitor redact /path/to/history.sqlite3 --output /tmp/history-redacted.sqlite3

10. Is It Safe To Bind 0.0.0.0?

Only if you also control the firewall or put the dashboard behind an authenticated reverse proxy. The UI and /api/v1/status are designed not to expose auth secret contents, but they can reveal account labels, quota state, model activity, and gateway health.

Direct non-loopback access also requires --allowed-host <hostname-or-ip> for the browser-facing authority; unexpected Host and Origin values are rejected. Keep the application on 127.0.0.1 and expose it through a reverse proxy when another device needs access. For example, protect the proxy with basic auth or an external access layer before forwarding https://quota.example/ to http://127.0.0.1:4515/.

The supported reverse-proxy topology is a dedicated hostname at the root path. Path-prefix deployments such as https://example/tools/quota/ are not supported in v1 because the UI assets and browser API requests use root-relative paths.

11. How Can I Notice Failures Without Prometheus?

Prometheus is optional. For a simple local check:

curl -fsS http://127.0.0.1:4515/api/v1/alerts | jq '.ok'

For systemd services, Restart=on-failure is included in the examples. Use systemctl status codex-quota-monitor --no-pager for system services and systemctl --user status codex-quota-monitor --no-pager for rootless user services.