ChatGPTClaudeGrok / X / CursorGemini

DeepSeek Harness workspaceController unavailable: restore

TroubleshootingPublished 2026-10-30Author: DeepSeek Plugin Market
DeepSeek HarnessDSHworkspaceControllerworkspacesession lossworkspace.jsonprofiles
DeepSeek Harness projects and sessions vanish, and new ones fail with workspaceController is unavailable. Move suspect dirs out first, then fix in cost order.

The failure most easily mistaken for "all my data is gone" is actually three different problems sharing one error: workspace create failed: gateway/service-unavailable: typert gateway: workspace/create: active Service "workspaceController" is unavailable. Reinstalling, rolling back, or creating a new profile when you see that line almost never helps, because the bad data is still in place. The right order is to start with the zero-cost, reversible action and only pay more as you go (#10885).

DeepSeek Harness: Why step one is "move it out", not "fix it back"

Moving a suspect directory out of the sessions root is reversible: nothing is deleted or edited, it just stops the startup scan from hitting it. One restart then tells you whether the data still exists, at the lowest possible cost.

  1. Quit DSH completely, including the tray icon and any leftover process in Task Manager.
  2. Copy the whole ~/.dsh/sessions tree to another drive as a cold backup.
  3. Move every *.archived-*, renamed directory, and directory of unknown origin outside the sessions root.
  4. Start DSH and check whether the workspaces and sessions come back.
  5. If they do, the data is intact and only the scan stage was broken; if not, continue to priorities two and three.

The community result was hard evidence: after moving the renamed directory out, 23 workspaces and 867 sessions were rebuilt with zero loss, and all 824 v4 plus 43 older-format sessions decompressed normally.

DSH plugin: Priority 1: a session directory renamed in place (#10885)

When an external tool renames a session directory in place to archive it and then creates a same-named directory at the original path, one session-id lineage maps to two directories, and the startup scan throws and fails the whole list.

  1. Think about whether an external bridge manages sessions — a Feishu bot, for example. In this case the bridge lacked resume_session in the SDK and rolled its own archive: feishu-<id>/ → feishu-<id>.archived-<ts>/, then created a new <id>/.
  2. Note the "incubation" period: the desktop app had not restarted for six days, and sessions are scanned only at startup, so the problem stayed hidden.
  3. The trigger was the rc.2→rc.3 nightly auto-update forcing a restart; the first full scan hit the renamed directory.
  4. The failure chain: JsonlSessionPersistence.assertStoredIdentity() throws a plain Error (corrupt session log ...: header id ... and cwd identify ...), while listArtifacts() filters only SessionFormatUnsupportedError and SessionPersistenceCorruptionError.
  5. The plain error escapes → the listing throws → dsh-workspace never activates → workspaceController is unavailable.

So this is not a version issue: the community compared the three related packages between rc.2 and rc.3, found identical MD5s, and reproduced the same error on rc.2's CLI against the same session root.

The community posted a 12-line patch on a fork (branch fix/list-survives-relocated-session-logs): during the list scan (expectedId === undefined), throw the identity mismatch as the typed SessionPersistenceCorruptionError so listArtifacts skips it through the existing corruption branch, while targeted loads still throw the plain error. It is not merged upstream.

DeepSeek Harness: Priority 2: workspace.json fails the schema (#10908)

workspace.json can be valid JSON and still fail: if any record in the workspaces array misses a field or has a non-ISO timestamp, the domain cannot open, workspaceRegistry never activates, and the shell only shows a generic service-unavailable.

  1. Quit the app completely and back up ~/.dsh/storages/workspace.json.
  2. Open the file and check every record in workspaces for path, title, sessionIds, createdAt, and updatedAt.
  3. Fill timestamps in as ISO-8601 strings, for example 2026-01-01T00:00:00.000Z. The original error reads createdAt: expected string, received undefined.
  4. If a record is confirmed obsolete, delete it and remove the matching id from global.workspaceIds.
  5. Restart the app, start the host separately, and confirm stderr no longer shows entries did not activate and workspace/create returns ok: true.

The confusing part is that a new profile, a version rollback, and a reinstall all fail to bypass it, because the bad record stays in the same storage file. It also has nothing to do with credentials, HOME, or directory permissions.

DSH Plugin: Priority 3: profile root unreachable, silent exit at startup (#10678)

When double-clicking the desktop app produces no window and the process exits with ENOENT ... mkdir ...\.dsh\profiles\desktop, that comes from the first line of withLock — mkdirSync — with no try block in front of it.

  1. Check whether DSH_HOME is a directory junction pointing elsewhere (for example G:\deepseek\.dsh pointing at %USERPROFILE%\.dsh).
  2. Check whether the junction target still exists: open the junction path in Explorer; a dangling junction lists no contents.
  3. Rename the earlier .dsh.bak back to %USERPROFILE%\.dsh, or rebuild the junction to point at it.
  4. Start again. If it recovers, this was the cause.
  5. If you never needed that junction layer, deleting it and restoring the backup in place is simpler — every extra junction is another failure point.

The mechanism is worth remembering: when a recursive: true mkdir crosses a dangling junction, it reports ENOENT on the leaf path, not "the junction is broken", so the log looks as if it is complaining that the profiles directory does not exist.

DeepSeek Harness: How to tell the three apart

Look at the symptom shape first: if the error is workspaceController unavailable but the window opens, check the first two; if no window appears at all, check the third.

SymptomKey evidencePriority
Empty workspace list, creating fails*.archived-* or renamed directories under the sessions rootMove them out (priority 1)
Same, with no renamed directoryMissing fields in ~/.dsh/storages/workspace.jsonFix schema (priority 2)
Double-click exits, no windowLog shows ENOENT mkdir profiles\desktopFix the junction (priority 3)

DSH plugin: Confirming the recovery is real

Do not just look for a list in the window; confirm all three stages — scan, activate, create/delete — work.

  1. After restarting, count the workspaces and compare against the directory count in the backup.
  2. Open any old session and confirm the history renders and the conversation can continue.
  3. Create a new workspace and see whether workspace create failed returns.
  4. Restart once more to confirm the state persists — if it only works inside the current process, another bad record is still there.

Cautions

Move and back up before deleting anything; the data is usually still there.

  1. Do not delete sessions first. Someone in the community suggested "delete everything and it will work", which throws away your ability to diagnose. Move first, back up first.
  2. Do not test with a new profile. The bad data lives in the same storage, and a new profile reads the same copy.
  3. Do not count on a version rollback. This chain is version-independent; the three related packages are byte-identical across both versions.
  4. Change the archiving tool's behavior. Any external tool that renames in place inside sessions/ recreates this state on every archive cycle.
  5. Fully quit before restarting. Multiple instances scan at the same time, and when something breaks it becomes harder to tell which copy of the data is bad.

If all three steps are done and it is still unavailable, capture the full host stderr — the real cause is not in the generic UI message, only in that log.See DeepSeek Harness sessions won't open: null turn/end reason for the related case.

ChatGPTClaudeGrok / X / CursorGemini

FAQ

After a DeepSeek Harness update all projects and sessions are gone and it reports workspaceController is unavailable — is the data lost?

Usually not lost: in the community case, moving a renamed session directory out of the sessions root let DeepSeek Harness rebuild all 23 workspaces and 867 sessions with zero loss; 824 v4 files and 43 older-format sessions all decompressed normally. Back up and move things out before judging.

Why does moving a suspect session directory out of the profile restore workspaces in DeepSeek Harness?

DeepSeek Harness restores the workspaces because sessions are scanned only at startup, and assertStoredIdentity() throws a plain Error that listArtifacts() does not filter. The plain error escapes, the whole listing fails, dsh-workspace never activates, and workspaceController stays pending.

workspace.json is valid JSON, so why does it still stop the DeepSeek Harness workspace service?

Valid JSON is not schema-valid in DeepSeek Harness: every record in the workspaces array needs path, title, sessionIds, createdAt, and updatedAt, and the timestamps must be ISO-8601 strings; one missing field throws a DomainError plus ZodError, the domain fails to open, and workspaceRegistry never activates.

Can rolling back to an older version, creating a new profile, or reinstalling DeepSeek Harness bypass the workspaceController error?

No, none of those moves bypasses the workspaceController error in DeepSeek Harness, because the bad record is still in the same storage file and a new profile reads the same data. Rolling back does not help either — the community compared the three related packages between rc.2 and rc.3 and their MD5s were identical.

The DeepSeek Harness desktop app exits with no window and the log shows ENOENT mkdir .dsh\profiles\desktop — what now?

When DeepSeek Harness exits with no window and logs ENOENT mkdir .dsh\profiles\desktop, first check whether DSH_HOME is a directory junction whose target was renamed or moved. The first line of withLock is mkdirSync(profile, {recursive:true}) with no try block, so crossing a dangling junction reports ENOENT on the leaf path. Rename the backup back or rebuild the junction, then start again.

Related Terms

workspaceController
workspaceController is the DeepSeek Harness desktop service that adds, removes, and lists workspaces. It depends on workspaceRegistry activating; when any upstream step fails it stays pending and the UI only shows a generic active Service is unavailable.— https://github.com/deepseek-ai/deepseek-harness/discussions/10908
assertStoredIdentity
assertStoredIdentity is the JsonlSessionPersistence method that checks whether a session file's header id matches the path derived from cwd. After a directory is renamed in place it throws a plain Error, bypassing the type filter in listArtifacts.— https://github.com/deepseek-ai/deepseek-harness/discussions/10885
workspaceRecord
A workspaceRecord is the structure stored for a workspace and must contain path, title, sessionIds, createdAt, and updatedAt, with timestamps as ISO-8601 strings. Any record that fails this triggers a schema validation failure.— https://github.com/deepseek-ai/deepseek-harness/discussions/10908
directory junction
A directory junction is a Windows reparse point that points at another directory, often used to place DSH_HOME on a different drive. If the target is moved or renamed the junction dangles, and a recursive mkdir fails with ENOENT on the leaf path.— https://github.com/deepseek-ai/deepseek-harness/discussions/10678

Sources