paddock service install --help states an unconditional promise that the code only keeps conditionally. If PADDOCK_DATA_DIR is set in the shell you run install from, that path is written into the generated unit — and the help text says it isn't.
The behaviour looks deliberate and defensible. The help text and the changelog are what's wrong, and they are wrong in the direction that leaves a user with two instances they believe are one.
What the help text promises
SERVICE_USAGE, packages/server/src/cli/args.ts:305-308:
-d, --data-dir <path> Only if you want an instance SEPARATE from your
terminal one. Omitted by default on purpose, so
`paddock service` and a bare `paddock` are the same
~/.paddock instance reached two ways.
The 0.68.0 changelog repeats it (packages/server/CHANGELOG.md:99): "…into a terminal are the same ~/.paddock instance reached two ways".
What the code does
resolveDataDir, packages/server/src/cli/service/index.ts:78-91:
const chosen = opts.dataDir ?? ctx.envDataDir;
if (chosen !== undefined) {
const resolved = path.resolve(chosen);
return { dataDir: resolved, explicit: resolved };
}
return { dataDir: defaultDataDir(ctx.homeDir), explicit: undefined };
ctx.envDataDir is process.env.PADDOCK_DATA_DIR from the installing shell, threaded at packages/server/src/cli/paddock.ts:181-183. When explicit is set, --data-dir <path> goes into the unit's argv.
So the true precedence is:
explicit --data-dir flag > PADDOCK_DATA_DIR in the installing shell > omitted
not "omitted unless you pass the flag".
The source is upfront about why, and the reasoning is sound (index.ts:82-85):
An env var set in the installing shell is an explicit choice too — but it is one the service would NOT inherit, so it gets written into the unit rather than silently dropped in favour of ~/.paddock.
That is the right call. A systemd --user unit or a LaunchAgent does not inherit your shell environment, so not baking it in would mean install silently ignored a data dir the user had clearly selected.
Failure scenario
A user with PADDOCK_DATA_DIR=/srv/paddock-data exported in one terminal — a container shell, a direnv block, a one-off PADDOCK_DATA_DIR=… paddock service install — runs install. The unit gets --data-dir /srv/paddock-data.
Later, from a normal login shell without that export, they type paddock. That instance opens ~/.paddock: no projects, no chats. They now have two instances and the --help they just read told them there would be one. paddock service status reports Data: /srv/paddock-data, which is the only place the truth is visible, and only if they think to look.
Severity
Medium. No data is lost — but "where did my projects go" is a confusing failure, and the documentation actively steers the user away from the explanation. It also matters more than it used to: --here is gone (#803), so --data-dir / PADDOCK_DATA_DIR is now the mechanism for picking which instance you get, which the 0.68 What's New entry says in as many words.
Blocks a docs claim
Yes, mildly. website/src/content/docs/guides/running-as-a-service.md describes the unit contents. A docs pass touching that page would otherwise copy the help text's promise verbatim and publish the same error on the website.
Suggested fix
Keep the behaviour; correct the words. Something like:
-d, --data-dir <path> Only if you want an instance SEPARATE from your
terminal one. Omitted by default, so `paddock service`
and a bare `paddock` are the same ~/.paddock instance
reached two ways — unless PADDOCK_DATA_DIR is set in
this shell, which is recorded in the unit too (a
service does not inherit your shell environment).
…plus the same qualification in running-as-a-service.md. Optionally, have install print the resolved data dir when it came from the environment rather than a flag, so the decision is visible at the moment it is made.
paddock service install --helpstates an unconditional promise that the code only keeps conditionally. IfPADDOCK_DATA_DIRis set in the shell you runinstallfrom, that path is written into the generated unit — and the help text says it isn't.The behaviour looks deliberate and defensible. The help text and the changelog are what's wrong, and they are wrong in the direction that leaves a user with two instances they believe are one.
What the help text promises
SERVICE_USAGE,packages/server/src/cli/args.ts:305-308:The 0.68.0 changelog repeats it (
packages/server/CHANGELOG.md:99): "…into a terminal are the same~/.paddockinstance reached two ways".What the code does
resolveDataDir,packages/server/src/cli/service/index.ts:78-91:ctx.envDataDirisprocess.env.PADDOCK_DATA_DIRfrom the installing shell, threaded atpackages/server/src/cli/paddock.ts:181-183. Whenexplicitis set,--data-dir <path>goes into the unit's argv.So the true precedence is:
not "omitted unless you pass the flag".
The source is upfront about why, and the reasoning is sound (
index.ts:82-85):That is the right call. A
systemd --userunit or a LaunchAgent does not inherit your shell environment, so not baking it in would meaninstallsilently ignored a data dir the user had clearly selected.Failure scenario
A user with
PADDOCK_DATA_DIR=/srv/paddock-dataexported in one terminal — a container shell, adirenvblock, a one-offPADDOCK_DATA_DIR=… paddock service install— runsinstall. The unit gets--data-dir /srv/paddock-data.Later, from a normal login shell without that export, they type
paddock. That instance opens~/.paddock: no projects, no chats. They now have two instances and the--helpthey just read told them there would be one.paddock service statusreportsData: /srv/paddock-data, which is the only place the truth is visible, and only if they think to look.Severity
Medium. No data is lost — but "where did my projects go" is a confusing failure, and the documentation actively steers the user away from the explanation. It also matters more than it used to:
--hereis gone (#803), so--data-dir/PADDOCK_DATA_DIRis now the mechanism for picking which instance you get, which the 0.68 What's New entry says in as many words.Blocks a docs claim
Yes, mildly.
website/src/content/docs/guides/running-as-a-service.mddescribes the unit contents. A docs pass touching that page would otherwise copy the help text's promise verbatim and publish the same error on the website.Suggested fix
Keep the behaviour; correct the words. Something like:
…plus the same qualification in
running-as-a-service.md. Optionally, haveinstallprint the resolved data dir when it came from the environment rather than a flag, so the decision is visible at the moment it is made.