How to Troubleshoot Common CodexBar Issues: Swift Menu-Bar Debugging Guide
Troubleshoot CodexBar issues by verifying background processes, inspecting probe logs via the Debug pane or CLI, and checking the observable UsageStore state for provider failures, UI refresh errors, or Keychain conflicts.
CodexBar is a Swift 6 menu-bar application developed by steipete/CodexBar that separates data fetching from UI rendering to monitor LLM provider usage. When the menu icon freezes, widgets display placeholders, or macOS Keychain prompts appear unexpectedly, the solution requires tracing data flow through specific architectural layers. This guide provides concrete commands and source code references to diagnose and resolve typical failures.
Understanding CodexBar's Architecture
The codebase is organized into four distinct modules that dictate where failures originate:
Sources/CodexBarCore– Background probes that communicate with LLM providers (Codex RPC, Claude PTY, OpenAI web scraper).Sources/CodexBar– Houses the observableUsageStore(the single source-of-truth for snapshots, errors, and status checks) and theStatusItemControllerthat drives menu-bar rendering.Sources/CodexBarWidget– A WidgetKit extension that reads shared snapshots and renders home screen widgets.Sources/CodexBarCLI– The bundledcodexbarcommand-line tool for diagnostics and log exports.
All background operations flow through UsageStore.runRefresh, which orchestrates provider data collection, observable state updates, and UI refresh triggers via @Observation.
Common Issue Categories and Root Causes
Most failures fall into four distinct categories based on where the data flow breaks down.
Provider Probe Failures
Symptoms include "⚠️ OpenAI Dashboard requires login" banners, empty usage numbers, or repeated error messages in the dropdown menu. These originate in Sources/CodexBarCore when UsageFetcher, ClaudeUsageFetcher, or CostUsageFetcher encounter network timeouts or authentication changes.
Check UsageStore.errors and UsageStore.probeLogs to view raw failure details.
Menu-Icon State Issues
When the icon fails to update, displays the wrong provider, or shows a stale usage bar, the problem resides in StatusItemController. Specifically, examine the iconObservationToken observation logic and the iconStyle computation in UsageStore, as these drive the visual state.
Widget Visibility Problems
Widgets showing placeholders or no data indicate a breakdown between UsageStore and CodexBarWidgetProvider. The CodexBarWidgetProvider reads snapshots produced by UsageStore; if the snapshots array is empty or the timeline fails to reload, the widget stalls.
Keychain and Browser Cookie Prompts
macOS may prompt for "Chrome Safe Storage" or similar keychain access even after uninstalling CodexBar. This occurs when stray processes survive uninstallation or login items persist.
Step-by-Step Troubleshooting Workflow
Follow this sequence to isolate the root cause without exposing secrets or modifying system files.
-
Verify process status – Confirm the app and CLI helper are running:
pgrep -fl 'CodexBar|CodexBarCLI' -
Enable Debug tools – Open CodexBar → Settings → Debug and enable "Expose troubleshooting tools" to view real-time probe logs and export them to temporary files.
-
Run CLI diagnostics – Execute a comprehensive status check that reveals provider enablement, error strings, and last-refresh timestamps:
codexbar diagnose --allExample output:
Provider: codex Enabled: true Last refresh: 2026‑07‑07 09:12:03 Status: ok Error: <none> Provider: claude Enabled: true Last refresh: 2026‑07‑07 09:11:58 Status: error Error: “Claude probe failed: network timeout” -
Inspect UsageStore state – For provider-specific debugging, dump raw probe output using Swift methods from
Sources/CodexBar/UsageStore.swift:import CodexBar @MainActor func dumpClaudeLog() async { let store = UsageStore.shared // Writes codexbar-claude-probe.txt to tmp and opens Finder await store.debugDumpClaude() }Alternatively, retrieve OpenAI logs programmatically:
await store.dumpLog(toFileFor: .openai) -
Resolve Keychain conflicts – If prompts persist after uninstall, kill stray processes, remove login items, and disable Keychain access via CLI:
codexbar settings set keychainAccess disabled open -a CodexBar
Diagnostic Commands and Code Snippets
Force Widget Timeline Refresh
When the widget appears stuck, trigger an immediate reload from your code or the Shortcuts app:
import WidgetKit
func refreshWidgetNow() {
WidgetCenter.shared.reloadAllTimelines()
}
Provider-Specific CLI Diagnosis
Isolate a single failing provider to reduce noise in logs:
codexbar diagnose --provider claude
Debug Dump via Swift REPL
Access the shared store instance to verify internal state without UI interference:
let store = UsageStore.shared
print(store.snapshots.last?.errorDescription ?? "No errors")
Summary
- Verify process existence with
pgrepbefore debugging UI or data issues. - Provider failures expose themselves in
UsageStore.errorsand viacodexbar diagnose --provider <name>. - Menu-icon staleness stems from
StatusItemControllerobservation tokens orUsageStore.iconStylelogic. - Widget blanks indicate missing snapshots or failed timeline updates in
CodexBarWidgetProvider. - Keychain prompts require disabling access via
codexbar settings set keychainAccess disabledand removing lingering login items.
Frequently Asked Questions
Why does CodexBar show "⚠️ OpenAI Dashboard requires login" even when I'm logged into the browser?
This error originates in the web scraper probe within Sources/CodexBarCore when the authentication cookie becomes invalid or the session expires. Run codexbar diagnose --provider openai to confirm the specific error string, then re-authenticate in your default browser or check UsageStore.probeLogs for HTTP 403 status codes indicating credential expiry.
How do I stop macOS from asking for Keychain access every time CodexBar refreshes?
The prompt appears because the app reads browser cookies stored in macOS Keychain. To disable this access safely, run codexbar settings set keychainAccess disabled in Terminal and relaunch the app. If prompts persist after uninstalling, consult docs/keychain-prompts.md to remove orphaned login items and kill background agents that survived the uninstall process.
Why is my Home Screen widget showing a placeholder instead of usage data?
Widgets rely on CodexBarWidgetProvider reading from the shared UsageStore snapshot. If the snapshot is empty (due to a probe failure) or the timeline hasn't refreshed, the widget displays a placeholder. Force a reload by calling WidgetCenter.shared.reloadAllTimelines() or check UsageStore.snapshots to verify data exists before the widget renders.
How can I export logs to send to support without exposing my API keys?
Use the built-in CLI safe-export functions: codexbar diagnose --all generates a sanitized summary containing timestamps, error messages, and provider status without including authentication tokens. For raw probe debugging, await store.debugDumpClaude() writes logs to a temporary file that excludes sensitive HTTP headers.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →