DeepSeek Harness 环境变量与凭据排查:git 调用失败、凭据变量名匹配漏掉、子进程不走代理与凭据格式代差
DeepSeek Harness(DSH)里有一类故障的共同特征是「环境与文件的形态假设不一致」:子进程环境清洗把 git 的配置组删得不完整,导致所有 git 调用失败;凭据类变量的名字匹配模式覆盖不全,.env 里的敏感值被原样传给子进程;把代理变量设成空值**(而不是取消设置)会让所有子进程静默直连;以及桌面端与命令行写入的凭据文件形态不同,旧版命令行一启动就失败。** 四条的排查思路一致:先把环境变量与文件的实际内容打印出来,再对照工具期望的形态——先看事实,再改配置(#9293、#9285、#9373、#9845)。
DeepSeek Harness 环境清洗把 git 配置组删坏:所有 git 调用失败
一句话结论:清洗按名字删掉了 git 配置组的键名变量,却留下了计数与取值变量——这组变量被拆散后 git 看到「计数为正却找不到对应的键」,直接拒绝解析命令行配置,于是子进程里所有 git 调用都失败。 报错形态是 missing config key GIT_CONFIG_KEY_0 或「无法解析命令行配置」(#9293)。
DeepSeek Harness git 配置组三步确认与处置
- 确认判据:报错里点名了 git 配置组的环境变量;而且这些变量确实存在于你启动 DSH 的那个环境里(#9293)。
- 打印出来核对:
env | grep -E '^GIT_CONFIG_(COUNT|KEY_|VALUE_)'
# 预期:能看到计数与取值存在、而键名缺失 —— 即被删散的那一组
(#9293)
- 规避:启动 DSH 之前把整组变量移除(而不是只删一部分),让 git 回到读配置文件的常规路径(#9293)。
- 修法方向:清洗应当按组原子化处置——要么整组保留、要么整组删除,不能逐项按名字匹配(#9293)。
- 顺带一条安全提醒:讨论里指出取值变量仍被转发,也就是说即便键被删掉,值仍可能出现在子进程环境里——如果你在环境变量里传过带凭据的 git 配置,需要注意这一点(#9293)。
DeepSeek Harness 凭据类变量的名字匹配漏了:PAT / CRED / PASSPHRASE
一句话结论:敏感变量匹配只覆盖包含少数几个常见关键词的写法,于是以 PAT 结尾、或以 CRED、PASSPHRASE 命名但不含那些关键词的变量不会被清洗,被原样传给每个派生进程。(#9285)
DeepSeek Harness 凭据变量名三步确认与处置
- 确认判据:在环境里列出你自己的凭据变量名,检查是否含那些常见关键词;含则会被清、不含则会被转发(#9285)。
- 立即可做的缓解:把凭据变量改名成含常见关键词的形式(例如带
TOKEN),从而被清洗覆盖(#9285)。 - 更稳妥的做法:不要依赖「按名字清洗」来保护凭据——改用只注入必要变量的启动方式(白名单式启动),从源头减少泄漏面(#9285)。
- 修法方向:把匹配扩展到
(^|_)(PAT|CRED|PASSPHRASE)(_|$)这类边界形态,并可进一步用CRED[A-Z]*覆盖带后缀的写法(讨论中给出的建议)(#9285)。
DeepSeek Harness 空代理变量让子进程静默直连
一句话结论:代理变量只被判断「有没有定义」,空字符串被当成有效用户值传给子进程,并因此触发了一条本为某类代理保留的清理逻辑——结果子进程完全不读代理变量,表现为静默直连、没有任何诊断。 症状是宿主自己走了代理,但所有 Node 子进程(含 stdio 类 MCP 与子代理)直连(#9373)。
DeepSeek Harness 代理变量三步确认与处置
- 确认判据:环境里存在已设置但为空的代理变量(例如一个为空、另一个有值并存);宿主可访问、子进程不可访问(#9373)。
env | grep -iE '^(http_proxy|https_proxy|all_proxy|no_proxy)='
# 预期:看到某个变量等号后为空
DeepSeek Harness 凭据文件格式代差:命令行启动即失败
一句话结论:桌面端写的是结构化文档**(带版本号与引用记录),而旧版命令行把每个顶层键都当成「引用名到字符串」的映射,于是结构化文档被拒;反过来当前上游又要求结构化文档、拒绝扁平格式——两边刚好相反。** 报错形态是凭据文件里某个字段「必须是字符串」,随后整棵插件树加载不了(#9845)。
DeepSeek Harness 凭据文件三步确认与处置
- 确认判据:桌面端可用、命令行启动失败;报错点名凭据文件里的字段类型(#9845)。
- 看文件形态:打开数据目录下的凭据文件,确认它是扁平映射还是结构化文档(#9845)。
- 处置(推荐):把命令行升级到开始读取结构化文档的那条版本线——升级后它既能读结构化文档,也会在启动时把旧的扁平文件原地升级(#9845)。
- 临时共存方案:让两边的凭据插件指向不同的文件(按 profile 区分),避免互相覆盖格式(#9845)。
- 两个易错细节:讨论中指出版本号字段在两种写法里有类型差别,以及外来的顶层键只应告警、不应阻断启动——这两条适合写进你的排查清单(#9845)。
- 验证:升级后重启命令行,预期正常启动并能在文件中看到结构化形态(#9845)。
DSH插件 排查注意事项
这四条的排查第一步都一样:把「事实」打印出来——环境变量、代理变量、凭据文件形态。 八条要点:
- 「按名字删变量」这种清洗天生不安全:删一半比不删更危险(#9293)。
- 成组的配置变量必须整组处置(#9293)。
- 别依赖关键字清洗来保护凭据,白名单式启动更可靠(#9285)。
- 空字符串 ≠ 未设置:这条在代理与目录类变量上都反复出现(#9373)。
- 「宿主能通、子进程不通」优先查代理变量(#9373)。
- 凭据文件格式先看再改:扁平与结构化两种形态不要混写(#9845)。
- 升级是这条最省事的解法:新版命令行会读结构化文档并原地升级旧文件(#9845)。
- 修复状态如实:四条在讨论所指版本里都未修;本文给出的处置均为用户侧规避(整组移除变量、改名、取消设置空变量、升级命令行版本),官方侧未宣布修复。
环境变量类问题排查成本高,因为「看不见的东西」最容易出错。若你希望把「环境里装了什么」这一层先看清,与其在各处手敲命令,不如用 DSH Plugin Hub 这类可视化插件市场:已安装列表、装卸历史与系统日志集中在一个面板里。

来源:Discussion #9293、Discussion #9285、Discussion #9373、Discussion #9845。
常见问题
DeepSeek Harness 里所有 git 调用失败,是因为子进程环境清洗时按名字删掉了 git 配置组里的键名变量,却留下了计数与取值变量,这组变量被拆散后 git 看到计数为正却找不到对应的键,直接拒绝解析。绕过办法是在启动 DeepSeek Harness 之前把整组 git 配置环境变量移除,而不是只删其中一部分。
DeepSeek Harness 中宿主走了代理而子进程全部直连,是因为判断逻辑只区分「有没有定义」,空字符串被当成有效用户值传给了子进程,并因此触发了一条本为某类代理保留的清理逻辑,结果子进程根本不读取代理变量。规避办法是在启动前把空的代理变量彻底取消设置,或把它显式填成同一个地址。
会泄漏——DeepSeek Harness 当前的敏感名匹配只覆盖包含常见关键词的写法,像以 PAT 结尾、以 CRED 或 PASSPHRASE 命名但不含那些关键词的变量会漏掉,被原样传给派生进程。可行的缓解是把自己的凭据变量改成包含常见关键词的命名,或使用只注入必要变量的启动方式;修法方向是把匹配扩展到这些前缀与后缀形态。
DeepSeek Harness 命令行版启动即失败、报凭据文件里的字段必须是字符串,根因是凭据文件格式的代差:桌面端写的是结构化文档(带版本号与引用记录),而旧版命令行把每个顶层键都当成「引用名到字符串」的映射,于是结构化文档被拒;反过来当前上游又要求结构化文档、拒绝扁平格式。办法是升级命令行到开始读取结构化文档的那条版本线;如果要临时共存,可以让两边的凭据插件指向不同的文件。
这几个 DeepSeek Harness 问题的共同排查思路是:它们都属于「环境与文件的形态假设不一致」。排查时先打印出实际的环境变量与文件内容,再对照工具期望的形态——例如 git 配置组是否完整、代理变量是否为空串、凭据文件是不是结构化文档。先看事实再改配置,能省掉大量试错。
相关术语
- GIT_CONFIG_COUNT / GIT_CONFIG_KEY_n / GIT_CONFIG_VALUE_n
- 这三个(一族)是 git 支持的「通过环境变量传入配置」机制:计数变量声明条目数,键与取值变量按序号成对出现。它们必须整组一致,任何一项被单独删除或保留都会让 git 拒绝解析命令行配置。— https://github.com/deepseek-ai/deepseek-harness/discussions/9293
- 环境清洗(scrubbedParentEnv)
- 环境清洗是 DeepSeek Harness 在启动子进程前对继承环境做的处理,目的是移除可能泄漏的敏感变量。它按变量名模式匹配删除,因此模式覆盖不全或删除粒度不当都会造成问题。— https://github.com/deepseek-ai/deepseek-harness/discussions/9285
- NODE_USE_ENV_PROXY
- NODE_USE_ENV_PROXY 是一类用于让运行时读取代理环境变量的开关,在部分实现里它是为特定代理类型保留的。误删或误设它会导致子进程完全不读取代理变量、表现为静默直连。— https://github.com/deepseek-ai/deepseek-harness/discussions/9373
- .credentials.yaml
- .credentials.yaml 是 DeepSeek Harness 存放凭据的文件,位于数据目录下。它有两种形态:扁平的「引用名到值」映射,以及带版本号与记录列表的结构化文档;不同版本的程序对这两种形态的支持不一致。— https://github.com/deepseek-ai/deepseek-harness/discussions/9845
来源
- #9293 — scrubbedParentEnv 删掉了 GIT_CONFIG_KEY_n 但保留 COUNT/VALUE,导致所有 git 调用失败· deepseek-ai(GitHub Discussions)
- #9285 — Child-process env scrub misses PAT/CRED/PASSPHRASE token names· deepseek-ai(GitHub Discussions)
- #9373 — [Bug][http-proxy] A blank proxy variable makes every Node child connect directly· deepseek-ai(GitHub Discussions)
- #9845 — CLI rc.6 fails to boot when ~/.dsh/.credentials.yaml is in DSH Desktop format· deepseek-ai(GitHub Discussions)