can1357/oh-my-pi · error · Error
Failed to delete session: ${error instanceof Error ? error.m
Error message
Failed to delete session: ${error instanceof Error ? error.message : String(error)} What it means
The selector's delete callback wraps any error from FileSessionStorage.deleteSessionWithArtifacts into a uniform 'Failed to delete session: <detail>' Error with the original as cause. It surfaces storage-layer failures (fs errors) during session deletion to the selector UI.
Source
Thrown at packages/coding-agent/src/modes/controllers/selector-controller.ts:1636
loadPinnedSessionIds(),
]);
sessions = loadedSessions;
const historyStorage = this.ctx.historyStorage;
const historyMatcher = historyStorage
? (query: string) => historyStorage.matchingSessionIds(query)
: undefined;
onSelectSession = session => this.handleResumeSession(session.path);
selectorOptions = {
onDelete: async (session: SessionInfo) => {
if (!(await this.#detachActiveSessionBeforeDeletion(session.path))) {
return false;
}
const storage = new FileSessionStorage();
try {
await storage.deleteSessionWithArtifacts(session.path);
return true;
} catch (error) {
throw new Error(
`Failed to delete session: ${error instanceof Error ? error.message : String(error)}`,
{ cause: error },
);
}
},
historyMatcher,
loadAllSessions: () => SessionManager.listAll(),
pinnedIds,
};
}
// Keep the fullscreen picker on the alternate buffer while a selected
// session is loaded and its transcript is rebuilt.
let overlayHandle: OverlayHandle | undefined;
const done = () => {
overlayHandle?.hide();
this.focusActiveEditorArea();
this.ctx.ui.requestRender();View on GitHub (pinned to 9690622007)
Solutions
- Check filesystem permissions on the session file and its directory and fix with chmod/chown
- If the file no longer exists, refresh the selector list and retry — the session is already gone
- Close processes locking the file (editors, sync clients) and retry
- Inspect error.cause for the precise fs error code and address that specifically
Example fix
// before
await storage.deleteSessionWithArtifacts(session.path);
// after
try {
await storage.deleteSessionWithArtifacts(session.path);
} catch (e) {
if (isEnoent(e)) return true; // already deleted
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
await fs.access(session.path).catch(() => { throw new Error(`Session file missing: ${session.path}`) });
await fs.access(path.dirname(session.path), fs.constants.W_OK); Type guard
function isDeletableSessionFile(p: string): boolean {
try { fs.accessSync(p, fs.constants.W_OK); return true; } catch { return false; }
} Try / catch
try {
await storage.deleteSessionWithArtifacts(session.path);
} catch (err) {
if (isEnoent(err)) return; // already gone — treat as success
if (err.code === "EPERM" || err.code === "EACCES") fixPermissionsAndRetry(session.path);
else throw err;
} Prevention
- Refresh the session list before deleting to avoid stale paths
- Keep sync clients (Dropbox/OneDrive) from locking the sessions directory
- Run with sufficient permissions for the sessions directory
- Handle ENOENT as success so concurrent deletions don't surface errors
When it happens
Trigger: Selecting 'delete' on a session in the session selector when storage.deleteSessionWithArtifacts(session.path) throws — e.g. ENOENT (session file already gone), EPERM/EACCES (no permission), or EBUSY (file locked).
Common situations: Session file removed by another process or a cleanup script while the selector is open; read-only session directory; syncing tool (Dropbox/OneDrive) holding locks on the session file; deleting across a mount that changed.
Related errors
- Cleanse session could not be persisted
- Session file not found: ${resolved}
- No artifacts directory found: {artifacts_dir}
- No artifacts directory found
- Unable to read Claude session ${info.id}: ${detail}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/aa42a13b3f19ca09.
Report an issue: GitHub.