dsh-cookie-janitor
IdentifiedExpires stale dsh-auth sign-in cookies once the Cookie request header passes 4 KiB, so per-port cookie accumulation can never reach Node's 16 KiB header limit (HTTP 431).
dsh-cookie-janitor
English | 中文
A DeepSeek Harness plugin that expires stale
dsh-auth-* sign-in cookies before the Cookie request header can reach Node's 16 KiB header
limit — the point where the HTTP parser answers 431 Request Header Fields Too Large before any
route, handler, or plugin runs.
The problem it fixes
@deepseek-ai/dsh-client-connection mints one browser cookie per request authority:
dsh-auth-<base64url(sha256("host:port"))> = v1.<payload>.<hmac>
; Max-Age=2592000; Path=/; HttpOnly; SameSite=Strict
The name embeds the authority, the lifetime is 30 days (cookieMaxAgeDays, default 30), and the
package never sends a deletion — there is no cleanup path at all. Cookies are host-scoped, not
port-scoped, so every port a browser has used for dsh web within those 30 days leaves one more
dsh-auth-* entry in the same jar for 127.0.0.1.
One pair is about 226 bytes. The parser's limit is 16 KiB of request headers: in testing, a request
whose Cookie header was 16,400 bytes returned 431 while 16,200 bytes still reached the
application. Roughly 69 accumulated cookies are therefore enough to lock the GUI out, and once it
happens nothing in the GUI can recover the page — every request dies before routing.
Install
dsh plugin add dsh-cookie-janitor
Directly from this repository:
dsh plugin add github:07-dot/dsh-cookie-janitor
Then restart dsh web (or the Desktop app) if your host does not hot-apply plugins.
What it does
On activation the plugin prepends one request listener to the listening http.Server. For each
request carrying dsh-auth-* cookies it measures the Cookie header; once the jar crosses the
budget it adds
Set-Cookie: <name>=; Path=/; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly; SameSite=Strict
for every cookie that is not the current request's own authority, oldest first, keeping
retain of them. The browser drains the jar on that response. The request itself is answered by
the normal pipeline: the hook only sets headers and never writes one, so routing, authentication,
and the SPA fallback are untouched.
Configuration
- id: cookie-janitor
name: dsh-cookie-janitor
config:
maxCookies: 8 # prune past this many dsh-auth cookies
maxHeaderBytes: 4096 # prune past this Cookie-header size
retain: 2 # cookies kept after a prune, including the current authority's
dryRun: false # log intended prunes without sending deletions
Pruning only starts above the budget, so a jar holding one cookie per live instance is never
touched. Several live authorities on one host (Desktop plus dsh web on port 3080, say) keep
working until the jar crosses the budget; after that the oldest entries are the ones expired, and a
reaped instance signs in again from its printed URL.
Manual rescue
GET /__dsh-cookie-janitor expires every dsh-auth-* cookie the request carries and prints the
observed statistics — largest Cookie header, most cookies seen, total pruned. Use it when a jar is
already unusable: open it in the same browser that holds the cookies, then reopen the DSH URL.
When you do not need it
The Desktop app does not accumulate these cookies: its main window talks to the Host through the
dsh-app://app/ protocol handler, which forwards exactly one cookie held in the shell's memory and
withholds set-cookie from the page jar (checked against DSH 0.2.1-rc.5). The exposure is the
web profile in a real browser, where the jar is shared across every port used within the cookie
lifetime. The plugin is harmless where it has nothing to prune — it emits no headers below the
budget.
It also cannot help with a Cookie header that is large for reasons other than dsh-auth-*
cookies; those are left alone deliberately.
Requirements
- DSH
0.2.1-rc.1or newer on the same 0.2.x line (engines.dsh). - No runtime dependencies, no build step, no install scripts.
Development
npm test
The suite drives the real apply() against a fake context and a fake response: budget gating,
retain, byte-only pruning, dryRun, duplicate-pass protection, the rescue route, authority
matching, and config normalization.
License
MIT
Comments
Loading…
Similar plugins
Keeps DeepSeek Harness desktop dsh-auth-* session cookies bounded by deleting stale ones during the token exchange performed on every launch, so random-port accumulation cannot reach the 16 KiB reques
★ 0
dsh plugin --profile web add dsh-cookie-fixby ALingStudio
DSH desktop plugin: sweeps leftover login-cookie files on every start so they cannot pile up past the 16KB request-header limit (HTTP 431 / "Web authentication failed").
★ 0
MIT
JavaScript
Oct 31, 2026
dsh plugin --profile web add dsh-cookie-sweepby dududreamer
Collapses the port-suffixed dsh-auth-* cookie pile so the DeepSeek Harness desktop shell never exhausts Node's 16 KB request-header budget.
★ 0
MIT
JavaScript
Nov 1, 2026
dsh plugin --profile web add dsh-cookie-janitorby kevindawn11-hash
Cap DSH desktop session cookie lifetime to avoid HTTP 431 / Web authentication failed startup crash. 修复 DSH 桌面端 dsh-auth-* cookie 累积导致的启动崩溃。
★ 1
MIT
JavaScript
Oct 31, 2026
dsh plugin --profile web add dsh-cookie-guardby jitianjiyan
为本地监听器预留足够的请求头预算,并在启动后退休旧启动 cookie,避免桌面欢迎握手被 431 永久锁死。
★ 26
↓ 2.7k/wk
MIT
JavaScript
Oct 31, 2026
dsh plugin --profile web add dsh-auth-cookie-guardby ridistant8-art
大肥鱼出品 · DSH 桌面版登录 cookie 百分表:浮窗显示请求头占用百分比(过半变红),带一键清理按钮,防止启动 72 次后被 431 挡住。
★ 8
MIT
JavaScript
Nov 2, 2026
dsh plugin --profile web add dsh-cookie-meter