Skip to content

Troubleshooting

Common problems and how to check what is actually happening, rather than guessing.

kasl has no log file. Diagnostic output goes through tracing to stderr, and is silent unless RUST_LOG or KASL_DEBUG is set:

Terminal window
RUST_LOG=kasl=debug kasl watch --foreground

RUST_LOG=kasl=trace gives more detail; KASL_DEBUG=1 is a shorthand equivalent to RUST_LOG=kasl=debug for kasl’s own messages. Reproduce the problem with one of these set before doing anything else below - most of the following sections just point you back here.

Everything lives under one data directory:

Platform Path
Windows %LOCALAPPDATA%\lacodda\kasl
macOS ~/Library/Application Support/lacodda/kasl
Linux ~/.local/share/lacodda/kasl

Inside it: kasl.db (SQLite database), config.json (settings and API credentials), and session cookie files (.jira_session_id, .si_session_id) written after a successful login. GitLab authenticates with a personal access token on every request, so it has no session file.

  1. Run it in the foreground to see activity as it happens:
    Terminal window
    RUST_LOG=kasl=debug kasl watch --foreground
  2. Check for an already-running daemon before starting another:
    Terminal window
    # Linux/macOS
    ps aux | grep kasl
    # Windows
    tasklist | findstr kasl
    Stop it cleanly with kasl watch --stop before restarting.
  3. If the workday starts too late or too early, adjust activity_threshold (seconds of continuous activity required to start a workday) via kasl setup. See Configuration.

Pauses are not detected, or are detected too eagerly

Section titled “Pauses are not detected, or are detected too eagerly”

pause_threshold (seconds of inactivity before a pause starts) and min_pause_duration (minutes before a pause is kept) control this - reconfigure with kasl setup. An absence spent away from the machine (meeting in another room, laptop closed) leaves no trace at all; record it by hand with kasl pauses add.

Only one process should hold the database at a time. Stop any running daemon first:

Terminal window
kasl watch --stop

Then check that nothing else is writing to kasl.db (a second watch instance, a report running concurrently). If the file itself looks suspect:

Terminal window
sqlite3 "<data dir>/kasl.db" "PRAGMA integrity_check;"
Terminal window
kasl setup # recreate interactively
kasl setup --delete # wipe it and start over

config.json is plain JSON; a jq . config.json or python -m json.tool config.json will point at a syntax error if the file was hand-edited.

Jira and SiServer passwords are stored in the OS keyring (Credential Manager / Keychain / Secret Service), not in config.json. On Linux, a background kasl watch daemon needs a running Secret Service provider (e.g. gnome-keyring or kwallet) to read the stored password without a terminal to prompt at; on a headless box without one, credential lookups fail silently and Jira/SiServer features are skipped. GitLab’s access token and the reporting server’s auth_token are stored directly in config.json, not the keyring - keep that file’s permissions private.

Jira or SiServer authentication fails repeatedly

Section titled “Jira or SiServer authentication fails repeatedly”

Delete the stale session file and let the next request log in again:

Terminal window
rm "<data dir>/.jira_session_id"
rm "<data dir>/.si_session_id"

If that does not help, re-run kasl setup to re-enter credentials - they may have expired or changed on the server side.

GitLab uses a personal access token (gitlab.access_token in config.json), not a session. Confirm the token is valid and has read_user + read_repository scope, and that gitlab.api_url points at the instance root (no /api/v4 suffix).

Report submission is refused with a productivity warning

Section titled “Report submission is refused with a productivity warning”

kasl report --send refuses to submit when the day’s productivity is below min_productivity_threshold (the monthly kasl sum --send has no such check) (see Configuration). This is intentional - it is the safeguard the removed kasl breaks command used to defeat. Record any genuine absence the monitor missed with kasl pauses add before retrying; that is the only supported way to raise the number.

kasl autostart enable tries Task Scheduler first, then falls back to a HKCU\Software\Microsoft\Windows\CurrentVersion\Run registry entry if that fails. Check both:

Terminal window
schtasks /query /tn KaslAutostart
reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v Kasl

kasl autostart status reports which one (if either) is active.

Grant Accessibility and Input Monitoring permissions under System Settings -> Privacy & Security, then restart kasl watch. Without them the OS silently withholds keyboard/mouse events.

kasl autostart enable installs a LaunchAgent at ~/Library/LaunchAgents/com.lacodda.kasl.plist. Reload it manually if needed:

Terminal window
launchctl unload ~/Library/LaunchAgents/com.lacodda.kasl.plist
launchctl load ~/Library/LaunchAgents/com.lacodda.kasl.plist

The activity monitor reads raw input devices. Add your user to the input group and re-login:

Terminal window
sudo usermod -a -G input $USER
ls -la /dev/input/

kasl autostart enable installs a systemd user unit. Check it directly:

Terminal window
systemctl --user status kasl
systemctl --user enable --now kasl
  • Configuration - all settings referenced above
  • watch - the activity monitor
  • pauses - recording missed absences
  • setup - creating and resetting configuration
  • autostart - platform autostart details