Skip to content

Troubleshooting

No activity is being recorded

Cause. AppCoordinator re-checks permissions before starting services and skips ActivityTracker entirely if Accessibility access is not granted (AXIsProcessTrusted() returns false). This is deliberate graceful degradation, not a crash — nothing in the UI screams about it beyond the Settings → Permissions status.

Fix. Open Settings → Permissions and grant Accessibility access, then restart tracking. Both permissions are polled every 5 seconds plus a distributed-notification observer for Accessibility changes, so the UI should reflect a newly granted permission without a full app relaunch.

No screenshots are being captured

Cause. Same pattern as above, for Screen Recording: CGPreflightScreenCaptureAccess() gates ScreenshotManager. Screen Recording grants require the user to approve a system dialog (CGRequestScreenCaptureAccess()), and on some macOS versions the app must be relaunched after the grant for ScreenCaptureKit to actually start capturing, even though the permission shows as granted.

Fix. Grant Screen Recording in Settings → Permissions, then fully quit and reopen GrotTrack if captures still are not appearing after a minute.

The Chrome extension shows "GrotTrack not running" / tab data never appears

Work through this in order — each step rules out one link in the chain described in Native Messaging.

  1. Is the native host manifest installed at all? Check ~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.grottrack.tabtracker.json exists. If not, install it from Settings → Browser in the app.
  2. Does it still contain the placeholder origin? If allowed_origins contains chrome-extension://EXTENSION_ID_PLACEHOLDER/, ChromeExtensionInstaller.checkInstallation() reports .needsExtensionID — Chrome will refuse to launch the host for any real extension ID against a manifest that only allows the placeholder. Find the extension's ID on chrome://extensions (Developer Mode) and enter it in Settings → Browser, which rewrites the manifest via updateExtensionID(_:).
  3. Does the manifest's path still point at a real binary? checkInstallation() returns .binaryMissing(expectedPath:) if the file at path is not executable — this happens if GrotTrack.app was moved after the manifest was written, since path is captured at install time from Bundle.main.bundlePath. Reinstall the host from Settings → Browser after moving the app.
  4. Is the extension actually loaded and enabled? A rejected native messaging connection from an extension ID mismatch surfaces in the extension's own service worker console (chrome://extensions → Details → Inspect views: service worker), not in GrotTrack.
  5. Is the data just stale? BrowserTabService.isConnected treats tab data as gone after 10 seconds without an update — if Chrome is minimized, closed, or the active window has no tabs (e.g. a picture-in-picture or DevTools-only window), this is expected, not a bug.

Tab title/URL is wrong or from the wrong window

Cause. background.ts queries chrome.tabs.query({ active: true, currentWindow: true }) — "current window" means whichever Chrome window most recently had focus from Chrome's own perspective at the moment the event fired, which can lag behind very fast window switching (the push is debounced 300ms per event).

Fix. This is a timing characteristic of the debounce, not a configuration problem. If it is consistently wrong rather than occasionally lagging, confirm you don't have multiple Chrome profiles each with the extension installed and both talking to the same host — only one profile's data is meaningful to a single native host connection at a time.

Session labels never appear

Cause. SessionClassifier requires Apple Intelligence via the FoundationModels framework, available only on macOS 26+ with Apple Intelligence enabled and a supported device. It fails gracefully rather than erroring — sessions are still detected and grouped by SessionDetector, they simply have label: nil.

Fix. Confirm Apple Intelligence is enabled in System Settings and that the Mac meets Apple's hardware requirements for it. There is no in-app override to force classification on unsupported hardware.

Disk usage is higher than expected

Cause. Screenshot storage is a function of tracking hours per day and the configured interval — the README estimates ~30–50 MB/day at a 30-second interval with 7-day full-screenshot retention and 30-day thumbnail retention, both defaults.

Fix. Lower the screenshot interval's frequency (raise the seconds-per-capture value) or reduce retention windows in Settings → Storage, then run the manual cleanup action to reclaim space immediately rather than waiting for the next automatic cleanup at launch.

Auto-update never finds a new version

Cause. Sparkle reads SUFeedURL from Info.plist (https://rknightion.github.io/grotTrack/appcast.xml) and verifies every entry's EdDSA signature against the embedded SUPublicEDKey before offering it. If the GitHub Pages deployment for a given release failed (the update-appcast job runs only when build-release succeeds first), the feed simply will not list that version — Sparkle has nothing to reject, there is no update to see.

Fix. Check the update-appcast job's run for the release in question on GitHub Actions. A missing appcast entry means that job did not complete, not a client-side problem.

Still stuck?

Search or open an issue on GitHub, including your macOS version, whether Accessibility/Screen Recording are granted, and (for browser-tab issues) the extension's service worker console output.