Skip to main content
When something goes wrong, start with the startup checks below, then look through the categorized issues. Most problems trace back to missing environment variables, stale PID files, or corrupt data files — all recoverable.

Startup failures

These are the most common blockers when launching ollim-bot.

Missing environment variables

config.py validates required variables on import. If any are missing, the bot prints a message to stderr and exits immediately.
Missing required env vars: OLLIM_USER_NAME, OLLIM_BOT_NAME
Set them in .env or your environment.
DISCORD_TOKEN is checked separately in main.py:
Set DISCORD_TOKEN in .env
Both exit with code 1. Set the missing variables in your .env file (at the project root) and restart.
VariableRequiredWhere checked
DISCORD_TOKENYesmain.py
OLLIM_USER_NAMEYesconfig.py
OLLIM_BOT_NAMEYesconfig.py

Bot already running

The bot writes its PID to ~/.ollim-bot/state/bot.pid on startup and checks /proc/<pid>/cmdline for the string ollim-bot. If a match is found:
ollim-bot is already running (pid 12345)
If the previous process crashed without cleaning up the PID file, delete it manually:
rm ~/.ollim-bot/state/bot.pid
The file is normally deleted on exit via atexit.

No owner found

If bot.application_info() returns no owner, the bot prints:
warning: no owner found; scheduler and DM disabled
The bot stays online but cannot send DMs, run scheduled routines, or start the webhook server. The owner is automatically the Discord account that created the application — this error usually means the application was created by a team with no members.

Session issues

The bot reads ~/.ollim-bot/state/sessions.json on startup. If the file is missing or empty, it starts a fresh session. Check that the file exists and contains a session ID string:
cat ~/.ollim-bot/state/sessions.json
If the file contains a JSON object (starts with {), load_session_id() returns None and the bot starts fresh. This can happen if another tool writes JSON to the file. Replace it with just the session ID string.
The Agent SDK auto-compacts conversations when they grow too long. Each compaction produces a new session ID and a compacted event in session_history.jsonl. This is normal behavior — the bot detects the ID change in save_session_id() and logs it automatically.If compaction happens too frequently, the conversation is growing fast. Use /clear to start fresh, or use /compact to trigger a manual compaction at a natural breakpoint.
The append-only log at ~/.ollim-bot/state/session_history.jsonl records every lifecycle event. To inspect it:
cat ~/.ollim-bot/state/session_history.jsonl
Each line is a JSON object with session_id, event, timestamp, and parent_session_id. Use this to trace session transitions, find the last known good session ID, or understand what happened before a crash.To manually resume a specific session, write its ID to sessions.json:
echo -n "sess_abc123" > ~/.ollim-bot/state/sessions.json

Data directory issues

All persistent state lives in ~/.ollim-bot/. See the data directory reference for the full layout.
read_md_dir() catches ValueError, yaml.YAMLError, TypeError, and KeyError when parsing .md files. Corrupt files are logged as warnings and skipped — they do not crash the bot.To find corrupt files, check the bot’s log output for warnings, then inspect or delete the offending file from ~/.ollim-bot/routines/, reminders/, or webhooks/.
read_jsonl() skips blank lines and lines that do not start with {. Lines that start with { but contain invalid JSON raise json.JSONDecodeError and are not silently dropped — they crash the read. It also filters fields to only those known to the target dataclass, providing forward compatibility.If a JSONL file is entirely corrupted, delete it. The bot recreates these files on the next write:
rm ~/.ollim-bot/state/session_history.jsonl
All writes use atomic temp-file-then-rename (tempfile.mkstemp + os.replace). Manual edits to files in ~/.ollim-bot/ while the bot is running risk being overwritten or causing inconsistent state. Stop the bot first, make edits, then restart.
The ~/.ollim-bot/ directory is a git repository. If you manually edit files, the bot’s auto-commit on next write will include your changes in its commit. Use git log inside the directory to review the change history.

Google OAuth issues

The Google integration requires ~/.ollim-bot/state/credentials.json from the Google Cloud Console. Without it, all Google-related commands (tasks, cal, gmail) and agent tools fail. Follow the Google OAuth setup guide to create and place this file.
~/.ollim-bot/state/token.json is auto-generated on first authentication and refreshed automatically. If the token becomes invalid (revoked scopes, credential rotation), delete it and re-authenticate:
rm ~/.ollim-bot/state/token.json
ollim-bot tasks list
The next Google API call triggers a browser-based OAuth flow to generate a new token.

Scheduling issues

The scheduler polls the routines/ and reminders/ directories every 10 seconds and registers APScheduler jobs. Check:
  1. The bot printed scheduler started: N jobs on startup (visible in the console).
  2. The .md file has valid YAML frontmatter with a cron (routines) or run_at (reminders) field.
  3. The id field in the YAML is unique — duplicate IDs cause one to overwrite the other.
  4. The owner was found on startup (no "warning: no owner found" message). The scheduler does not start without an owner.
Background forks that exceed the ping budget get tool errors from ping_user and discord_embed. The user is not notified — the tool returns an error to the agent, which decides how to proceed.Check the budget state:
cat ~/.ollim-bot/state/ping_budget.json
The available field shows remaining pings. The bucket refills 1 ping per 90 minutes, capped at a capacity of 5. Use /ping-budget in Discord to view a formatted status. See ping budget for details.

Fork issues

Replying to a background fork message starts an interactive fork that resumes from that fork’s session. This relies on ~/.ollim-bot/state/fork_messages.json, which maps Discord message IDs to fork session IDs.Records older than 7 days are pruned on every read. If the background fork message is older than 7 days, the mapping no longer exists and the reply is treated as a normal message.
Interactive forks have an idle timeout. The scheduler checks every 60 seconds — after idle_timeout minutes of inactivity, it prompts the agent to exit. After another timeout period, it escalates with a stronger prompt. The agent always decides the exit strategy (save_context, report_updates, or exit_fork).If the fork is truly stuck, use the exit buttons on the fork embed, or run /clear to reset the entire session.

Permission issues

The default permission mode is dontAsk. In this mode, non-whitelisted tools are silently denied without prompting the user in Discord.Switch to a more permissive mode with the /permissions command:
ModeBehavior
dontAskNon-whitelisted tools silently denied (default)
defaultNon-whitelisted tools trigger Discord approval prompt
acceptEditsFile edits auto-approved, others prompt
bypassPermissionsAll tools approved
The _session_allowed set persists across interactive forks but resets on /clear.
In default or acceptEdits mode, the bot sends a Discord message with reaction-based approval. The prompt has a 60-second timeout — if you miss it, the tool is auto-denied. Check that you are in a mode that sends prompts (default or acceptEdits, not dontAsk).

Diagnostic files

Quick reference for where to look when debugging.
FileWhat it tells you
~/.ollim-bot/state/sessions.jsonCurrent session ID (or missing = no active session)
~/.ollim-bot/state/session_history.jsonlTimeline of session lifecycle events
~/.ollim-bot/state/bot.pidPID of running bot instance
~/.ollim-bot/state/ping_budget.jsonCurrent ping budget state and counters
~/.ollim-bot/state/pending_updates.jsonQueued background fork summaries
~/.ollim-bot/state/fork_messages.jsonDiscord message to fork session mappings
~/.ollim-bot/state/inquiries.jsonActive button inquiry prompts
The ~/.ollim-bot/ directory is git-tracked. Run git log --oneline inside it to see a chronological record of all data changes.

Next steps