langgenius/dify · error · Error

cannot resolve %APPDATA% on Windows

Error message

cannot resolve %APPDATA% on Windows

What it means

A bare Error thrown by the win32 platform's configDir (sys/index.ts:101) when appDataDir() returns undefined or ''. appDataDir reads `getEnv('APPDATA') ?? getEnv('LOCALAPPDATA')` — so the throw fires only when BOTH APPDATA and LOCALAPPDATA are unset/empty on Windows. On a healthy Windows install these are always set by the OS/user profile; their absence indicates a broken environment. Linux/darwin use different factories and never hit this. The error blocks any operation that needs the config dir (hosts.yml path, etc.).

Solutions

  1. Set the env vars explicitly before running difyctl (PowerShell): `$env:APPDATA="$env:USERPROFILE\AppData\Roaming"; difyctl ...`.
  2. For service accounts / Task Scheduler: configure the task to load the user profile, or set APPDATA/LOCALAPPDATA in the task's environment block to a writable dir.
  3. In containers, set APPDATA at image build time: `ENV APPDATA=C:\Users\ContainerAdministrator\AppData\Roaming`.
  4. For SSH sessions, ensure the user's logon profile loads (use a fully interactive shell or set the vars in the sshd environment).
  5. If the profile is genuinely broken, recreate it or pick an explicit config dir via any difyctl-supported XDG override (note: the win32 factory here does NOT honor XDG_CONFIG_HOME — only the linux factory does — so you must set APPDATA).

Example fix

# before — difyctl invoked with no APPDATA on Windows
> difyctl auth login
Error: cannot resolve %APPDATA% on Windows

# after — set APPDATA/LOCALAPPDATA explicitly (PowerShell)
$env:APPDATA = "$env:USERPROFILE\AppData\Roaming"
$env:LOCALAPPDATA = "$env:USERPROFILE\AppData\Local"
difyctl auth login
Defensive patterns

Strategy: validation

Validate before calling

// on Windows, assert APPDATA/LOCALAPPDATA are set before invoking difyctl
function assertWindowsProfile(): void {
  if (process.platform !== 'win32') return
  const appData = process.env.APPDATA ?? process.env.LOCALAPPDATA
  if (appData === undefined || appData === '') {
    throw new Error('set APPDATA/LOCALAPPDATA before running difyctl on Windows')
  }
}

Prevention

When it happens

Trigger: Running difyctl on Windows under a context where the user profile env vars weren't propagated: a service account, Task Scheduler with no profile, sshd with a minimal env, a stripped Docker/container image, or a process launched with a hand-built environment that omitted APPDATA/LOCALAPPDATA.

Common situations: Windows Server scheduled task running as SYSTEM (which has no APPDATA in the normal per-user sense); containers based on Windows Server Core with a minimal profile; CI runners (GitHub Actions windows-latest usually sets them, but custom self-hosted may not); SSH into a Windows host with a non-interactive shell that skips profile loading.

Related errors


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/803df10ccf0a8248. Report an issue: GitHub.

Appendix: source

Thrown at cli/src/sys/index.ts:101

    },
    cacheDir: () => {
      const xdg = getEnv(ENV_XDG_CACHE_HOME)
      return xdg !== undefined && xdg !== '' ? join(xdg, SUBDIR) : join(homedir(), '.cache', SUBDIR)
    },
    atomicReplace: posixAtomicReplace,
  }),
  darwin: () => ({
    id: () => 'darwin',
    configDir: () => join(homedir(), '.config', SUBDIR),
    cacheDir: () => join(homedir(), 'Library', 'Caches', SUBDIR),
    atomicReplace: posixAtomicReplace,
  }),
  win32: () => ({
    id: () => 'win32',
    configDir: () => {
      const appData = appDataDir()
      if (appData === undefined || appData === '')
        throw new Error('cannot resolve %APPDATA% on Windows')
      return join(appData, SUBDIR)
    },
    cacheDir: () => {
      const appData = appDataDir()
      if (appData === undefined || appData === '')
        throw new Error('cannot resolve %LOCALAPPDATA% on Windows')
      return join(appData, SUBDIR)
    },
    atomicReplace: win32AtomicReplace,
  }),
}

const defaultPlatformFactory: PlatformFactory = () => ({
  id: () => platform(),
  configDir: () => join(homedir(), '.config', SUBDIR),
  cacheDir: () => join(homedir(), '.cache', SUBDIR),
  atomicReplace: posixAtomicReplace,
})

View on GitHub (pinned to ef8544b173)