Skip to content

update_stack_env with isSecret:false silently fails to persist non-secret vars #109

Description

@strausmann

Symptom

Calling update_stack_env with a variable flagged isSecret:false returns { success: true, count/added: N } but the variable never appears afterwards in get_stack_env or get_stack_env_raw, and is not injected into the container. Reproduced live on v1.9.0 (AFFiNE stack, hhdocker03) — non-secret MAILER/indexer vars had to be written as isSecret:true (DB secret) to make them stick.

Root cause (verified against source)

  • mcp-dockhand src/tools/stacks.ts update_stack_env sends all variables — including isSecret:false — to PUT /api/stacks/{name}/env.
  • finsys/dockhand setStackEnvVars stores them as DB rows (non-secrets with isSecret:false). BUT the GET handler (src/routes/api/stacks/[name]/env/+server.ts) reads non-secrets from the .env file, not the DB (for non-git stacks). So an isSecret:false DB row is an orphaned, invisible row: not surfaced by get_stack_env, never written to .env (so absent from get_stack_env_raw), never injected.
  • Net: non-secret vars cannot be set via update_stack_env at all — only via update_stack_env_raw.

Secondary bug — misleading description

The tool description states: "When false/omitted, value is written to the .env file as plain text" — this is false. The value goes to the DB /env endpoint and is then ignored on read. The description promises .env behaviour the endpoint does not deliver.

Impact

Silent data-loss-of-intent: callers believe non-secret config was set (success:true), but nothing persisted. The summary.added from #105 reports the payload count, not what actually persisted, so it doesn't catch this.

Proposed fix (options)

  1. Auto-route isSecret:false vars to the .env (via the /env/raw path) so update_stack_env behaves as its description promises (unified setter), OR
  2. Reject/error on isSecret:false vars with a clear message pointing to update_stack_env_raw.
    Plus: correct the misleading description, and make summary/added reflect what actually persisted (secrets vs .env).

Follow-up to #105 (stack-env two-store ergonomics).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions