Moving dsh plugins to a custom DSH_HOME safely

Install & Get StartedPublished 2026-10-19Author: DeepSeek Plugin Market
DeepSeek HarnessDSH pluginDSH_HOMEpathpermissionsisolation
Moving dsh plugins to a custom DSH_HOME: environment variables, launch flags, permissions, shared machines and a safe migration path.

I moved a dsh plugin install to a custom DSH_HOME after the system disk filled up, and the first lesson was that the install command is not in charge. DeepSeek Harness follows the root that the running process reads, so a new path is really a new boundary. The notes below record what moved with that boundary and what had to be carried by hand.

Why a dsh plugin install follows DSH_HOME

DSH_HOME is the root the process reads, so every install path and every runtime lookup is derived from it rather than from the command alone.

The default root sits in the user home, next to caches and downloads. DeepSeek Harness itself is small, but session snapshots, plugin packages and build caches accumulate over months. Moving that data to a separate disk turns a recurring space problem into a one-time migration cost.

The second reason was isolation. I kept two configurations, one for stable plugins and one for experiments, and switching environment variables by hand meant losing track of which one was active. Separate roots made each configuration explicit at launch, and a mis-installed package became easy to spot.

Changing the root does not move existing content. That surprised me on the first attempt, because the new directory was empty while the old plugins were still on the old disk. The variable is a pointer; the content lives wherever the pointer used to aim. The DSH Plugin Hub entry is useful for checking the package names before you reinstall them.

This is why the migration conversation should start with the boundary rather than with the destination. Decide which root belongs to which environment, confirm who can write to it, and only then run the install. The path itself is the least interesting part of the decision.

Setting DeepSeek Harness DSH_HOME with an environment variable

A variable in the shell profile suits a permanent root, because every process launched from that shell inherits the same value.

Personal machines and containers benefit most from this approach. The setting survives a new terminal and a rebuilt container image, and it applies to the CLI and the client when both are started from the same environment. The cost is scope, since every dsh process under that user reads the same root.

Create the directory first and confirm that your user can write to it. An installer that reaches a read-only directory fails partway through, often after downloading packages. A quick write test before the install saves a confusing cleanup.

bash
echo "$DSH_HOME"
export DSH_HOME="$HOME/.local/share/dsh-alt"
mkdir -p "$DSH_HOME"
dsh plugin --profile web add <package>@<version>
dsh plugin list

The first line shows whether an older value is still active in the current terminal. The install writes into the profile under the new root, and the list command confirms that the package landed where you expect. If the list is empty, check the variable again before blaming the package.

Put the export in a shell profile only after the manual run works. That order keeps a typo from following you into every new terminal. It also gives you a known-good command to compare against when a later session behaves differently.

Switching DSH_HOME with a DSH plugin launch flag

A per-command value suits temporary roots, because it changes the target for one process without rewriting the shell environment.

Use it for a rehearsal profile, a second project or a quick comparison between two installations. The value applies to the command that carries it, so the rest of the shell keeps the default root. That narrow scope is the point.

Keep the flag and the variable from disagreeing. If both are present, the explicit per-command value usually wins, but the precedence is worth confirming in the CLI documentation for your version. Mixing the two without knowing which one is active produces installs that seem to vanish.

bash
export DSH_HOME="$HOME/.local/share/dsh-alt"
DSH_HOME="$HOME/.local/share/dsh-lab" dsh plugin list
DSH_HOME="$HOME/.local/share/dsh-lab" dsh plugin --profile web add <package>@<version>

Record the command in a small script when a project needs a stable temporary root. The script becomes documentation for the team and removes the need to remember the exact prefix. It also makes it obvious when someone launches the project without the intended root.

Sessions and caches do not merge between two roots. Two instances launched with different values behave like two separate installations, which is useful for testing and confusing for daily work. Choose one root per task and keep it for the whole task.

Sharing one machine between DeepSeek Harness plugin users

A shared machine needs one writable root per user, because configuration and session data are not designed for concurrent writers.

Give each account its own directory under a location the account owns. Set permissions so that only the owner can write, and avoid a group-writable root as a shortcut. Two users writing the same configuration file will eventually overwrite each other's plugins.

Common plugins can live in a separate read-only location rather than in a shared writable root. That keeps the shared set predictable while each user keeps private experiments and sessions. The read-only location should be treated as a package source, not as a live profile.

Record which root belongs to which user and environment. A short line in the team notes is enough, and it prevents the classic incident where a support session installs into the wrong account. The path is an operational detail that becomes important during handover.

Verify isolation with two concurrent sessions before trusting it. Install a small plugin in one root and confirm that the other list does not change. If both lists move together, the two processes are reading the same root despite the separate paths.

Migrating existing dsh plugins to a new root

The safe migration is a reinstall from a package list, because copying the old directory carries paths and permissions that no longer apply.

Export the package names and versions from the old installation first. The list is the source of truth for what must exist in the new root, and it is much easier to read than a directory tree. Keep it next to the migration note.

Prepare the new root and confirm writes before installing anything. Then install each package under the new DSH_HOME and watch the results. A failure at this stage is usually a permission problem or a package that needs a build step.

  1. Print the old DSH_HOME and confirm it is the root you intend to leave.
  2. Export the installed package names and versions.
  3. Create the new directory and confirm your user can write to it.
  4. Open a new terminal and set DSH_HOME to the new root.
  5. Reinstall the packages from the exported list.
  6. Copy session history and credentials selectively, then fix any absolute paths.
  7. Run the plugin list and open one plugin to confirm it loads.

Configuration deserves selective copying rather than a wholesale directory copy. Old files may contain absolute paths, cached build output or credentials tied to the old machine. Copy the parts you understand and leave the caches behind.

Credential files are the part people forget. They may live under the old root, and a copied profile can reference them by path. Move them deliberately, check permissions after the move, and confirm that the client can still authenticate before you delete the old directory.

What a custom dsh plugin root must keep aligned

The directory can move, but install, runtime and data must all resolve to the same root or the plugin will appear to disappear.

The most common failure after a move is a split between the shell that installed and the process that runs. One reads the new root while the other still reads the old one. The package exists, the list looks wrong, and no amount of reinstalling fixes it until the roots agree.

A custom root also changes the backup boundary. Sessions, plugin configuration and credentials now live on a different disk, so a backup that only covers the home directory misses them. Adjust the backup before the first real session, not after the first loss.

The root is a boundary, not a toggle. Once the boundary is clear, installation, runtime and recovery all have a stable address. That clarity is worth more than the specific path you choose, and it is the part of the migration that survives the next machine.

FAQ

Where do dsh plugins install after DSH_HOME changes?

After DSH_HOME changes, dsh plugins install under the new root, but only if the install process reads the same value. Print the variable before installing.

Should a DeepSeek Harness DSH_HOME use a variable or a flag?

A DeepSeek Harness DSH_HOME can use a variable for a permanent setup or a flag for a temporary switch. Confirm precedence when both are present.

Why do dsh plugins fail after pointing to a custom root?

dsh plugins often fail after pointing to a custom root because the directory is not writable. The installer needs to write configuration, packages and caches.

How do several users share DeepSeek Harness plugin installs?

Several users should give each DeepSeek Harness plugin install its own root and permissions. Shared read-only plugins can live in a separate location.

How do I migrate existing dsh plugins to a new DSH_HOME?

Migrate existing dsh plugins by exporting the package list, reinstalling under the new root and fixing paths in configuration. Copying the old directory carries stale paths.

Related Terms

DSH_HOME (data root)
DSH_HOME is the DeepSeek Harness root for configuration, sessions and plugin data. It determines both install targets and runtime reads.— https://deepseek-harness.github.io/deepseek-harness/guide/quickstart
environment variable (process config)
An environment variable is read when a process starts and suits a fixed DSH_HOME. It affects every dsh process launched from that shell.— https://github.com/deepseek-ai/deepseek-harness/blob/master/apps/cli/README.md
launch flag (command option)
A launch flag is passed with the start command and suits a temporary DSH_HOME. When combined with an environment variable, confirm precedence.— https://github.com/deepseek-ai/deepseek-harness/blob/master/apps/cli/README.md
multi-user isolation (separate roots)
Multi-user isolation gives each user a separate data directory and permissions, preventing configuration and plugin collisions on shared machines.— https://www.npmjs.com/package/@deepseek-ai/dsh

Sources