DeepSeek Harness unknown prompt variable {{cwd}} fix
unknown prompt variable "{{cwd}}" in section "deployment:persona-suffix"; registered variables: provider, model — the error already gives away half the answer: only two variables are registered now, and cwd is not one of them. It is not a typo; upstream deleted it. The deletion landed in 0.2.1-alpha.2, and the leftover line is in your config file, which an upgrade will not clean for you (#11152).
DeepSeek Harness: Before: the old version treated cwd as a built-in
Before alpha.2, cwd was a registered prompt variable, and the default persona suffix used it.
- The old system prompt had a persona suffix shaped like "Your working directory is {{cwd}}."
- That suffix was written into the profile's config patch.
- As long as the version still registered
cwd, interpolation worked and you saw nothing unusual. - This layer is "historical configuration": it travels with your profile, not with the release package.
- Remember it: every later problem comes from "config outliving code".
DSH plugin: When: alpha.2 removed the registration and default suffix
Commit 79bd3d8da7 (the first dsh-v0.2.1-alpha.2 tag) removed the cwd registration and the default persona suffix, handing the job to runtime context.
- After removal, only
providerandmodelremain as prompt variables. - The working directory is now supplied by the runtime context entry
working-directory:current. - This is a design change, not a defect — so it will not be "fixed back in the next version".
- Interpolation happens during request assembly, where unregistered names are a hard error.
- So there is no "emit it verbatim" fallback, and the whole turn fails.
DeepSeek Harness: After: the leftover line fails every turn
Upgrades do not rewrite your config, and the config editor writes the whole object back, so the old value is frozen in the profile.
- The leftover
{{cwd}}sits in one of three places: the profile'scordis.patch.yml, a home-level patch, or a preset line. - An upgrade replaces release package contents and does not rewrite these files.
- The config editor writes back the entire config object, not just the field you edited.
- The result: values materialized by older versions are preserved forever.
- Every request assembly hits the same unregistered name, which shows up as "every turn fails".
DSH Plugin: The timeline in one sentence
The old config referenced a variable name that was later deleted; the deletion happened in code, the leftover lives in config, and the two can never agree.
| Stage | Code side | Config side |
|---|---|---|
| Before alpha.2 | registers cwd | writes a suffix containing {{cwd}} |
| Upgrade to 0.2.1 | removes cwd registration | kept as-is |
| Now | only provider/model | interpolation fails every turn |
DeepSeek Harness: Two fixes: delete a line, or install the shim
The lasting fix is deleting that line; to get running first, install the compatibility plugin.
- Locate the text first: search for
{{cwd}}in the profile'scordis.patch.ymland in preset configs. - When found, delete that line (or the whole persona suffix), or switch to runtime context where the working directory is needed.
- Restart and confirm
unknown prompt variableno longer appears. - If you cannot change config right now, install the community shim:
dsh plugin --profile <your-profile> add \
"github:argszero/dsh-legacy-prompt-vars#808e73c2dd49208f373bbe6b077ba5d78fcbe6c8"
- After installing,
--dump-configshould show alegacy-prompt-varsmount entry, meaning dsh inserted it itself. - The community verified on a clean profile with the 0.2.1-rc.3 runtime: exit code 0 and the entry present.
DSH plugin: The shim's boundary
It only re-registers retired variable names; it does not repair the layer holding the old text.
- It lets a persona suffix containing
{{cwd}}assemble again, so turns stop failing. - But it does not know which other old variables your config still has, and unknown names will fail the same way.
- It is not on npm, so it can only be installed from a git spec with the commit pinned.
- It is mitigation, not a fix — the line that should be deleted is still in your config.
- So the advice is: use it to stop the bleeding, then schedule time to delete the config.
One-minute locate the leftover
The section name in the error plus one full search narrows it to a specific file.
- Note the section in the error, such as
deployment:persona-suffix. - Search for
{{cwd}}in the profile directory, starting withcordis.patch.yml. - Then check the home-level patch and preset configs, searching all three.
- Match what you find against the section name to confirm it is this occurrence and not a same-named copy.
- Back up files before changing them so you can roll back.
Cautions
Delete the stale reference instead of editing the release package.
- Do not edit the release package. Variable registration lives in core code, and package edits are lost on the next upgrade.
- Do not search only one file. Leftovers can sit in the profile patch, a home patch, or a preset.
- Do not treat the shim as a long-term solution. It maintains a compatibility layer for retired names.
- Record the section name in the error.
deployment:persona-suffixpoints straight at the leftover. - Back up config before upgrading. For this class, the best diagnostic material is the config diff before and after upgrading.
If the variable in your error is not cwd, the logic is identical: first see which variables are registered now, then find the old name in your config.See DeepSeek Harness won't start: triage, Node env, port 3080 for the related case.
FAQ
It is not a spelling issue in DeepSeek Harness. Upstream removed the cwd registration in 79bd3d8da7 (the first dsh-v0.2.1-alpha.2 tag), and only provider and model are registered now; the leftover {{cwd}} comes from an old profile patch or preset line.
The upgrade did not overwrite it because that line lives in your DeepSeek Harness profile config, not in the release package. And the config editor writes back the whole config object rather than the single field you edited, so values written by older versions are preserved permanently.
The failure is deliberate in DeepSeek Harness: interpolation happens during request assembly, where unregistered variable names are designed to be a hard error. There is no fallback that emits {{cwd}} verbatim, so the whole turn fails.
Yes, there is a community compatibility plugin for DeepSeek Harness, dsh-legacy-prompt-vars 0.1.0, which re-registers retired variable names so a persona suffix containing {{cwd}} can assemble again. It is not on npm and must be installed from a git spec.
No, installing the shim is not a fix in DeepSeek Harness: it only keeps turns alive and does not repair the layer holding the old text. The lasting fix is deleting the {{cwd}} line from the profile patch or preset.
Related Terms
- prompt variable
- A prompt variable is an interpolatable placeholder in the system prompt, such as provider and model, replaced with actual values during request assembly. Unregistered names are treated as hard errors.— https://github.com/deepseek-ai/deepseek-harness/discussions/11152
- persona suffix
- A persona suffix is a persona paragraph appended to the end of the system prompt and may reference prompt variables. It is usually part of user-defined configuration and is not rewritten by upgrades.— https://github.com/deepseek-ai/deepseek-harness/discussions/11152
- cordis.patch.yml
- This profile-level patch is `cordis.patch.yml`, a file recording user adjustments to plugins and prompts. Content written by older versions survives upgrades.— https://github.com/deepseek-ai/deepseek-harness/discussions/11152
- working-directory:current
- working-directory:current is the runtime context entry that replaced the cwd variable and supplies the current working directory. After upgrading, it is the recommended way to express the working directory.— https://github.com/deepseek-ai/deepseek-harness/discussions/11152
Sources
- #11152 — unknown prompt variable "{{cwd}}"· deepseek-ai (GitHub Discussions)
- deepseek-ai/deepseek-harness (source repository)· GitHub