Troubleshooting
Where Polytoken keeps its files
Section titled “Where Polytoken keeps its files”Polytoken keeps its own state in three directories. The defaults follow the XDG Base Directory specification and are the same on every platform, including macOS.
| Contents | Default location | Redirect with |
|---|---|---|
| Configuration file, skills, facets, subagents, hooks, themes | $XDG_CONFIG_HOME/polytoken (default: ~/.config/polytoken) | POLYTOKEN_CONFIG_PATH |
| Sessions, logs, provider login state | $XDG_DATA_HOME/polytoken (default: ~/.local/share/polytoken) | POLYTOKEN_DATA_PATH |
| Model catalogs discovered from dynamic providers | $XDG_CACHE_HOME/polytoken (default: ~/.cache/polytoken) | POLYTOKEN_CACHE_PATH |
A redirect variable names the directory itself: Polytoken uses the value
exactly as written and does not append polytoken. With
POLYTOKEN_DATA_PATH=/tmp/pt, sessions land in /tmp/pt/sessions. An unset or
empty variable falls back to the matching $XDG_* value, then to the default
inside your home directory.
If POLYTOKEN_CACHE_PATH, XDG_CACHE_HOME, and HOME are all unset or
empty, Polytoken cannot resolve the cache directory for dynamic provider
catalogs. Polytoken then skips caching, logs a warning, and still discovers
the catalogs live from the provider.
The .polytoken/ directory at the root of a project is a different thing from
the global config directory. It holds project-scoped configuration only; see
Checking your configuration.
Reading the logs
Section titled “Reading the logs”The daemon’s log, the interface logs, and crash logs all land in
$XDG_DATA_HOME/polytoken/logs/ (default: ~/.local/share/polytoken/logs/).
ls -lt ~/.local/share/polytoken/logs/ | headThe path in this example is the default location; substitute it when you have
set $XDG_DATA_HOME.
Run logs carry a timestamp and a process ID, so each run gets its own file:
2026-09-05T13-22-04Z-368502.logis the daemon’s log for the run with process ID 368502. The daemon writes structured JSON entries to this file. A daemon that runs in the background also redirects its stdout and stderr into the same file, so startup failures and panics appear alongside the JSON entries.- The conversation interface writes logs ending in
-tui.log; the configurator writes logs ending in-configui.log. - A crash log ends in
-tui.crash.logand marks an involuntary exit. The file records the session ID, the exit reason, and, for panics, a backtrace. Normal exits write no crash log. When a panic or daemon attachment lease loss writes a crash log, the TUI announces the file path after restoring the terminal. A lease-loss message also includes the path when the write succeeds.
Two controls set verbosity, one per process. For the daemon’s log, set
daemon.log_level; its values are error, warn, info (the default),
debug, and trace. For the interface logs, set RUST_LOG to a standard
tracing filter, for example RUST_LOG=debug; the default is info. Polytoken
reports an error instead of launching when RUST_LOG holds an invalid filter.
Polytoken does not delete old log files. Runs accumulate until you remove the files yourself.
For non-interactive runs, polytoken exec --print-session-logs mirrors the
session’s JSONL events and the run’s trace log to stderr while the run
executes. That trace log, trace.jsonl, lives in the session directory rather
than the logs directory. See CLI.
Inspecting a session on disk
Section titled “Inspecting a session on disk”Each session owns a directory under $XDG_DATA_HOME/polytoken/sessions/,
named by its session ID. Three files answer most questions:
log.jsonlholds the session’s event log: every prompt, reply, tool call, and marker, in order. Polytoken replays this file to rebuild the conversation when you resume. See Sessions.session.jsonholds the metadata the session picker reads, including the project directory, the title, and timestamps.record.jsonexists only while a daemon owns the session. It records the daemon’s port and process ID; the recorded process ID is howpolytoken sessionsdecides a listed session is live.
The same directory holds todo records, shell-job output, subagent transcripts, and the exec trace log for the session. When daemon.logging.persist_system_prompts is on, Polytoken also creates system-prompts/ and stores one 0600 text sidecar for each changed composed system prompt. Polytoken keeps the directory at mode 0700. The sidecars help you compare provider prompts after a run and do not participate in session replay or exports.
Polytoken stores full output for capped tool results in the session’s tool-results/ directory and sets each spill file to mode 0600.
Native context records and exported artifacts
Section titled “Native context records and exported artifacts”A native compaction boundary stays in log.jsonl as a durable provider-state record. The record lets Polytoken resume, measure, and convert the context without reconstructing provider state from mutable files. A crash before the boundary or portable transition becomes durable leaves the old context active. A crash after the record becomes durable lets the committed record win after restart. A subagent whose model uses native compaction keeps the same kind of records in its own subagent-*.jsonl transcript, under the same rules.
The /history projection and the TUI expose method, fallback, occupancy, and non-secret timing metadata. They do not expose the provider’s opaque continuation state. Feedback artifact exports apply a redaction layer to native records, while the on-disk session log remains lossless for Polytoken’s own resume path. Treat the raw session directory as sensitive.
polytoken sessions lists live sessions and removes stale registry entries as
a side effect. Add --all to list every session directory on disk, including
finished ones. Legacy sessions that predate session.json appear in the
--all listing but cannot be resumed.
When Polytoken resumes a large legacy session, Polytoken shows live migration progress while it converts the session. Migration can take several minutes for a session with extensive history or many subagent logs. You can interrupt the resume safely. A later resume retries the conversion and converges on the migrated session.
Conflicting session trees
Section titled “Conflicting session trees”A conflicting-session-tree error means Polytoken found both the legacy session directory and the migrated session directory for one session ID. Polytoken does not choose one tree automatically because the two trees may contain different history.
Polytoken keeps the original legacy tree in sessions-migration/<id>/legacy-backup while migration remains recoverable. A recreated legacy directory that contains only startup scaffolding moves to sessions-migration/<id>/recreated-stub/ so Polytoken can retry without deleting the scaffolding. Polytoken never treats a legacy directory containing log.jsonl as scaffolding.
To recover, stop any process that owns the session and resume the session again. When the legacy directory lacks log.jsonl, or migration artifacts remain, another resume converges automatically. Polytoken archives the scaffolding stub and either publishes the staged history or restores the backup for another retry. When both the legacy log.jsonl and a valid migrated session directory contain history, another retry cannot resolve the conflict. Polytoken refuses to choose either tree and preserves both. Keep both trees unchanged and seek assistance.
Checking your configuration
Section titled “Checking your configuration”Polytoken looks for a file named config.json, config.json5, config.toml,
config.yaml, or config.yml in the global config directory and in
.polytoken/ at the root of your project. A directory may hold exactly one of
them; two produce a load error naming both files. Project values override
global values, and a null in the project layer deletes a global key. Model-group
definitions use a different precedence rule: user/global definitions replace
project definitions, and project definitions replace shipped definitions. A
member of a model group cannot be null. Omit modelgroups.<name> to remove
that layer’s override and restore the lower-priority definition.
polytoken config validatechecks the merged result and prints the authoredactive_session.default_facetvalue. Add--useror--projectto check one layer alone; each mode prints that layer’s authored value or explains that daemon startup falls back toexecutewhen the key is unset.polytoken config editopens the project layer in your editor by default, or the user layer with--user, and validates before saving: the real file changes only after validation passes.polytoken config uiopens the interactive configurator.
String values in the file can reference an environment variable with ${VAR},
the common way to supply an API key. A referenced variable that is not set
fails the load, and polytoken config validate names it.
polytoken doctor runs the same startup checks the daemon runs and prints
each result as a checklist line. The checks cover the startup surface:
configuration, providers and models, permissions, shell behavior, hooks,
skills, facets, subagents, tools, and MCP servers. The command exits non-zero
when a check fails; MCP connection failures count as warnings. It starts no
session and leaves nothing behind.
Environment variables
Section titled “Environment variables”Polytoken reads these variables when it starts.
| Variable | Effect |
|---|---|
POLYTOKEN_CONFIG_PATH | Uses this directory as the config root, without appending polytoken. |
POLYTOKEN_DATA_PATH | Uses this directory as the data root, without appending polytoken. |
POLYTOKEN_CACHE_PATH | Uses this directory as the cache root, without appending polytoken. |
XDG_CONFIG_HOME, XDG_DATA_HOME, XDG_CACHE_HOME | Standard XDG locations, consulted when the matching POLYTOKEN_*_PATH variable is unset. |
RUST_LOG | Verbosity of the interface log files; the default is info. |
EDITOR | Selects the editor for polytoken config edit; the default is vi. For the interface’s drop-to-editor command, a configured tui.editor key wins, then VISUAL, then EDITOR; the default is vim. |
POLYTOKEN_SKIP_UPDATE_CHECK | Set to any value to skip the launch-time update check. Polytoken sets this itself when it re-launches after an update. |
POLYTOKEN_DISABLE_FEEDBACK | Set to 1 to disable manual feedback, including /feedback and Ctrl+Shift+F. |
POLYTOKEN_TUI_COLOR_MODE | Forces truecolor or 256 output when terminal color detection is wrong. See Installation. |
POLYTOKEN_TUI_DISABLE_KEYBOARD_ENHANCEMENT | Set to 1 to skip requesting the terminal’s extended keyboard protocol. |
POLYTOKEN_DAEMON_CREDENTIAL_FILE | Environment form of the daemon’s --credential-file flag. See Daemon Authentication. |
POLYTOKEN_OUTPOST_URL | Default URL for Outpost management commands that accept --outpost-url. See Outpost. |
POLYTOKEN_OUTPOST_TOKEN | Token for Outpost commands and polytoken connect when --outpost-token is omitted. See Outpost. |
OTEL_* | OpenTelemetry exporter settings, when trace export is enabled. See Telemetry. |
Bash hook handlers receive their own set of POLYTOKEN_* variables describing
the session; see Hooks.
When a provider fails
Section titled “When a provider fails”Raise daemon.log_level to debug, reproduce the problem, and read the newest
daemon log.
For a durable record, turn on daemon.logging.provider_autopsy. Each provider
failure then produces a redacted report under autopsies/ inside the session
directory, without the request or response contents. The same directory also
holds diagnostics for tool calls that failed to parse, and those contain the
raw malformed input, so treat autopsies/ as sensitive. Polytoken prunes
older reports automatically.
Polytoken also writes a small summary line to the daemon log when each
provider request starts and finishes. Those lines carry counts and sizes
only, never request contents, and they are always on at the default log
level. For a detailed size and structure breakdown of every provider
request, including successful ones, turn on
daemon.logging.provider_request_diagnostics in your configuration file,
or use the Provider request diagnostics toggle in the configurator’s
Daemon pane. The key is off by default because the breakdown adds
preparation work to each request. Provider autopsy works independently of
this key: autopsy keeps gathering the detail failure reports need even
when the diagnostics key is off.
The /feedback command can attach the current TUI log tail and screenshots to a
report. Ctrl+Shift+F opens the same form. See
Crash Reporting and Feedback.
The assistant stalls in extended reasoning
Section titled “The assistant stalls in extended reasoning”Some models reason for a long time before they produce an answer. When a response keeps producing reasoning without any visible text or tool call, Polytoken interrupts the provider stream, asks the model to answer or act, and retries the response. The retry keeps a session usable when reasoning runs away.
The retry sequence is scoped to a stretch without progress. When the model resumes writing text or calling a tool, Polytoken discards the accumulated retries and starts fresh, so earlier interruptions do not weigh on later productive work. A prompt you send after an interruption also starts fresh.
An interruption does not prove the model was repeating itself. Long, legitimate reasoning can trigger the interruption too. When Polytoken cannot get an answer or a tool call after several retries, it ends the turn with a note that says the response was stuck in a reasoning loop. Try sending the request again, or switch to a model that reasons less.
Checking language servers, themes, and definitions
Section titled “Checking language servers, themes, and definitions”Four read-only commands verify the pieces a session depends on: language servers, definitions, themes, and shipped resources.
polytoken lsp checklists every language server Polytoken knows and whether its binary resolves on this machine. Naming a server also runs its--versionprobe and reports the outcome in the exit code. See Language Servers.polytoken validate skill <target>,polytoken validate facet <target>, andpolytoken validate subagent <target>parse and validate one definition file, by name or by path, using the same logic the daemon runs at startup.polytoken theme validatechecks a theme file against the token catalog. See Themes.polytoken vfs lsandpolytoken vfs catlist and print the resources Polytoken ships, such as the default theme. See The Polytoken VFS.