NousResearch/hermes-agent · error
That project has no folder to move into
Error message
That project has no folder to move into
What it means
Thrown by moveSessionToProject when the project node selected for a session move has no folder cwd to anchor it. The desktop store resolves the target project's root working directory via projectRootCwd() from the $projectTree; if the node is missing (id not found) or is not a folder-backed project, cwd is null and the move is refused before any gateway RPC is issued. The backend's session.workspace.move requires a real cwd because it re-anchors both the session's directory grouping and any live agent.
Source
Thrown at apps/desktop/src/store/projects.ts:534
branch?: null | string
cwd?: string
git_repo_root?: null | string
}
// Re-home a stored session into another project's root folder — the fix for a
// chat created in the wrong directory. The backend replaces cwd + git identity
// (so the tree's grouping follows) and re-anchors any live agent bound to the
// row; here we mirror the move into the `$sessions` cache so both the flat list
// and the grouped tree reflect it before the next authoritative refresh.
export async function moveSessionToProject(
sessionId: string,
projectId: string,
profile?: null | string
): Promise<void> {
const cwd = projectRootCwd($projectTree.get().find(node => node.id === projectId))
if (!cwd) {
throw new Error(translateNow('sidebar.projects.moveNoFolder'))
}
const res = await gatewayRequest<WorkspaceMovePayload>('session.workspace.move', {
cwd,
session_key: sessionId,
...(profile ? { profile } : {})
})
const moved = res.cwd || cwd
setSessions(prev =>
prev.map(s =>
sessionMatchesStoredId(s, sessionId)
? { ...s, cwd: moved, git_branch: res.branch ?? null, git_repo_root: res.git_repo_root ?? null }
: s
)
)
void refreshProjectTree()
}View on GitHub (pinned to c896c09c42)
Solutions
- Verify the projectId exists in $projectTree.get() before calling, and refresh the tree if it is stale.
- Ensure the target node is a folder-backed project (has a root cwd) — virtual groupings cannot accept moved sessions.
- Guard the call with projectRootCwd(...) yourself and surface a 'pick a folder-backed project' message instead of letting it throw.
- Check the profile argument matches the tree you searched — a mismatched profile yields a node miss.
Example fix
// before
await moveSessionToProject(sessionId, projectId)
// after
const node = $projectTree.get().find(n => n.id === projectId)
if (!node || !projectRootCwd(node)) {
toast('Pick a project that has a folder.')
} else {
await moveSessionToProject(sessionId, projectId)
} Defensive patterns
Strategy: validation
Validate before calling
import { $projectTree } from '.../store/projects'
import { projectRootCwd } from '.../store/projects'
function canMoveToProject(projectId: string): boolean {
const node = $projectTree.get().find(n => n.id === projectId)
return Boolean(projectRootCwd(node))
} Type guard
function isFolderProject(node: ProjectNode | undefined): node is ProjectNode & { cwd: string } {
return Boolean(node && projectRootCwd(node))
} Try / catch
try {
await moveSessionToProject(sessionId, projectId)
} catch (e) {
if (e instanceof Error && e.message.includes('no folder')) refreshProjectTree()
else throw e
} Prevention
- Refresh $projectTree before user-initiated move/drop actions.
- Only render folder-backed projects as valid drop targets in the sidebar.
- Pass profile-consistent ids — never ids sourced from another profile's tree.
When it happens
Trigger: Calling moveSessionToProject(sessionId, projectId) where projectId does not exist in $projectTree.get(), or where the project node is a virtual/non-folder grouping that projectRootCwd() maps to null (e.g. a profile-level or synthetic node with no folder root).
Common situations: Stale project tree after the backend refreshed projects (node id changed or was removed), racing a project deletion with a drag-and-drop move in the sidebar, or passing a project id from a different profile.
Related errors
- Branch name is required.
- Missing URL
- Invalid data URL
- Not a directory: ${watchDir}
- Invalid profile name: ${value}
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/d7cddea43cade829.
Report an issue: GitHub.