Skip to content

desktop: OPENCODE_EXPERIMENTAL_FILEWATCHER is set into the service env but never read by the CLI #53417

Closed as not planned

Description

@kumu314

Summary

The desktop app forcibly injects OPENCODE_EXPERIMENTAL_FILEWATCHER=true into the background service's environment, but the CLI never reads that variable. It is dead. Meanwhile the variable that does control the watcher, OPENCODE_DISABLE_FILEWATCHER, is undocumented and absent from the config schema. Users and maintainers are both misled about what this knob does.

Environment

  • opencode version: 2.0.23 (desktop 2.0.23.0, bundled CLI opencode v2.0.23)
  • OS: Windows 11, 10.0.26200 build 26200, x64
  • Terminal: Desktop app (OPENCODE_CLIENT=desktop)
  • Shell: C:\WINDOWS\system32\cmd.exe
  • Install/channel: latest (release channel, packaged desktop build)
  • Active plugins: none configured

Reproduction

  1. Inspect the service process environment of opencode-cli.exe serve --service and note OPENCODE_EXPERIMENTAL_FILEWATCHER=true.
  2. Search the shipped CLI binary for that string: zero occurrences.
  3. Search the same binary for OPENCODE_DISABLE_FILEWATCHER: it is present and is what the code actually branches on.

Expected Behavior

An environment variable the host sets should be consumed by the child. If the intent is to force an experimental path, the child should read that name; if the intent is to expose an escape hatch, a supported switch should exist.

Actual Behavior

In resources/app.asar, the service environment is assembled as:

Object.assign(process.env, {
  ...t,
  OPENCODE_EXPERIMENTAL_ICON_DISCOVERY: `true`,
  OPENCODE_EXPERIMENTAL_FILEWATCHER: `true`,
  OPENCODE_CLIENT: `desktop`
})

Object.assign writes unconditionally, so these are overwritten on every spawn. That part is defensible for OPENCODE_CLIENT.

The problem is the filewatcher line. The CLI's actual gate is:

fs: {
  filewatcher: !y(process.env.OPENCODE_FILEWATCHER_DISABLE ?? process.env.OPENCODE_DISABLE_FILEWATCHER),
  ...
}

OPENCODE_EXPERIMENTAL_FILEWATCHER appears nowhere in the binary. Consequences:

  • The variable the desktop app sets does nothing at all
  • Setting it to false in the user or machine environment has no effect — the CLI ignores it, and the desktop app overwrites it anyway
  • The watcher is not experimental; it is on by default, since with neither disable variable set filewatcher evaluates to true
  • There is no config-schema key and no CLI flag for OPENCODE_DISABLE_FILEWATCHER, so the one working control is discoverable only by reading the bundled binary

The Object.assign makes the "experimental" naming actively harmful: it signals that the behaviour is gated, so nobody looks for the DISABLE variable that gates it. On this machine that misdirection cost real debugging time and was made worse by the watcher causing measurable harm — see the companion report on the watcher restart loop.

Additional Context

Verification performed

  • Counted occurrences of OPENCODE_EXPERIMENTAL_FILEWATCHER, EXPERIMENTAL_FILEWATCHER, and OPENCODE_EXPERIMENTAL_ICON in the 206 MB CLI binary: 0 each
  • Confirmed the detector works: OPENCODE_CLIENT (5), OPENCODE_DISABLE_AUTOUPDATE (2), XDG_DATA_HOME (8), session_message (111), watcher started (2) all found in the same file with the same method
  • Recovered the fs.filewatcher branch verbatim from the binary
  • Confirmed OPENCODE_EXPERIMENTAL_FILEWATCHER is absent from both the user and machine persistent environment, so this is not an inherited value being shadowed

Suggested fixes

  1. Stop setting OPENCODE_EXPERIMENTAL_FILEWATCHER in the desktop app, since it is inert
  2. Document OPENCODE_DISABLE_FILEWATCHER (and the OPENCODE_FILEWATCHER_DISABLE alias), or better, expose it as a proper opencode.json key
  3. If the flag is genuinely intended to be experimental, have the CLI read it and gate the code path on it

See also #53416 for the measured impact of the watcher churn this variable is misnamed for.

Related

  • watcher.ignore exists in the config schema but does not apply to globally-registered skill directories (ignores=0 is logged for them), which is the other half of the discoverability problem.

Activity

  1. github-actions commented on Oct 5, 2026

    @github-actions
    Contributor

    This issue doesn’t fully meet our contributing guidelines.

    What needs to be fixed:

    • Use the Bug Report template’s required Description field. The issue currently has a Summary heading instead.

    Please edit this issue to address the above within 72 hours, or it will be automatically closed.


    This issue might be a duplicate of existing issues. Please check:

    If you believe this was flagged incorrectly, please let a maintainer know.

  2. github-actions commented on Oct 8, 2026

    @github-actions
    Contributor

    This issue has been automatically closed because it was not updated to meet our contributing guidelines within the 72-hour window.

    Feel free to open a new issue that follows our issue templates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions