Summary
Factory Desktop persists unused sessions that contain no user prompt, assistant response, or token usage. These sessions remain visible in the session history as "New Session" or "Untitled" and accumulate across project folders.
A configured SessionStart hook makes the issue more visible because Factory writes a hidden user_only hook event into the transcript, but the logs show that Factory Desktop calls InitializeSession before the hook is executed. The hook therefore appears to amplify the persistence/visibility problem rather than create the session.
Environment
- Factory Desktop / Droid version:
0.183.0 (also observed on 0.182.0)
- Platform: macOS arm64
- OS: Darwin
25.5.0
- Session storage:
~/.factory/sessions/
- Global
SessionStart hook configured
Steps to reproduce
- Configure a global
SessionStart command hook.
- Use Factory Desktop across one or more project folders.
- Open or initialize sessions, including navigating away from a newly initialized draft without submitting a prompt.
- Inspect
~/.factory/sessions/<encoded-cwd>/ or the Factory Desktop session history.
The issue has also occurred while submitting a message to an existing session: at the same timestamp, Factory Desktop initialized a separate unused session.
Actual behavior
Factory creates and retains a transcript similar to:
{"type":"session_start","title":"New Session","cwd":"/path/to/project"}
{"type":"message","message":{"role":"user","content":[],"visibility":"user_only","hookEventName":"SessionStart","hookStatus":"completed"}}
Its settings contain zero usage:
{
"assistantActiveTimeMs": 0,
"tokenUsage": {
"inputTokens": 0,
"outputTokens": 0,
"cacheCreationTokens": 0,
"cacheReadTokens": 0,
"thinkingTokens": 0,
"factoryCredits": 0
}
}
A local scan found 40 such sessions across multiple encoded working-directory folders. Some older unused sessions contain only the session_start record, which indicates that hooks are not required for the underlying empty-session creation.
Expected behavior
An initialized draft should not be persisted in session history until it receives a real user message, or unused zero-token drafts should be hidden and garbage-collected automatically.
user_only lifecycle-hook events should not cause an otherwise unused draft to be treated as a meaningful session or refresh its apparent activity timestamp.
Relevant evidence
The observed sequence in the Droid log is:
Droid InitializeSession method called
[droid process] Spawning: droid exec --input-format stream-jsonrpc --output-format stream-jsonrpc
[JsonRpc] Handling initialize_session
[Session] Saving session settings (inputTokens=0, outputTokens=0)
[Hooks] Matched commands (eventName=SessionStart)
[Hooks] Hook execution completed
[SessionController] Session created
The process ancestry confirms that these Desktop-originated sessions are initialized by Factory:
factory-desktop
-> droid daemon --enable-child-ipc --listen ipc
-> droid exec --input-format stream-jsonrpc --output-format stream-jsonrpc
Workaround
The current workaround is to periodically delete sessions whose token usage is zero and whose transcript contains only session_start plus empty user_only SessionStart hook events.
Summary
Factory Desktop persists unused sessions that contain no user prompt, assistant response, or token usage. These sessions remain visible in the session history as "New Session" or "Untitled" and accumulate across project folders.
A configured
SessionStarthook makes the issue more visible because Factory writes a hiddenuser_onlyhook event into the transcript, but the logs show that Factory Desktop callsInitializeSessionbefore the hook is executed. The hook therefore appears to amplify the persistence/visibility problem rather than create the session.Environment
0.183.0(also observed on0.182.0)25.5.0~/.factory/sessions/SessionStarthook configuredSteps to reproduce
SessionStartcommand hook.~/.factory/sessions/<encoded-cwd>/or the Factory Desktop session history.The issue has also occurred while submitting a message to an existing session: at the same timestamp, Factory Desktop initialized a separate unused session.
Actual behavior
Factory creates and retains a transcript similar to:
{"type":"session_start","title":"New Session","cwd":"/path/to/project"} {"type":"message","message":{"role":"user","content":[],"visibility":"user_only","hookEventName":"SessionStart","hookStatus":"completed"}}Its settings contain zero usage:
{ "assistantActiveTimeMs": 0, "tokenUsage": { "inputTokens": 0, "outputTokens": 0, "cacheCreationTokens": 0, "cacheReadTokens": 0, "thinkingTokens": 0, "factoryCredits": 0 } }A local scan found 40 such sessions across multiple encoded working-directory folders. Some older unused sessions contain only the
session_startrecord, which indicates that hooks are not required for the underlying empty-session creation.Expected behavior
An initialized draft should not be persisted in session history until it receives a real user message, or unused zero-token drafts should be hidden and garbage-collected automatically.
user_onlylifecycle-hook events should not cause an otherwise unused draft to be treated as a meaningful session or refresh its apparent activity timestamp.Relevant evidence
The observed sequence in the Droid log is:
The process ancestry confirms that these Desktop-originated sessions are initialized by Factory:
Workaround
The current workaround is to periodically delete sessions whose token usage is zero and whose transcript contains only
session_startplus emptyuser_onlySessionStarthook events.