langgenius/dify · error · Error
cannot resolve %LOCALAPPDATA% on Windows
Error message
cannot resolve %LOCALAPPDATA% on Windows
What it means
Companion to [54]: a bare Error from the win32 cacheDir (sys/index.ts:107). The condition is identical because cacheDir also calls appDataDir(), which is `APPDATA ?? LOCALAPPDATA`. Practically this means: if APPDATA is set, cacheDir succeeds even though its error message names LOCALAPPDATA — the message is somewhat misleading. Only when BOTH are unset/empty does cacheDir throw. The cache dir holds transient data (downloads, temp) and is less critical than config, but its absence still blocks commands that need it.
Solutions
- Set APPDATA (and LOCALAPPDATA) as described in [54]; setting APPDATA alone satisfies appDataDir for both config and cache.
- Prefer setting both for clarity: APPDATA=...Roaming, LOCALAPPDATA=...Local.
- For service accounts, load the user profile or set the vars in the task environment.
- Note: difyctl's win32 factory does not honor XDG_CACHE_HOME; you must set the Windows env vars.
Example fix
# before — cache dir resolution fails on Windows > difyctl <cmd> Error: cannot resolve %LOCALAPPDATA% on Windows # after — set both Windows profile env vars $env:LOCALAPPDATA = "$env:USERPROFILE\AppData\Local" $env:APPDATA = "$env:USERPROFILE\AppData\Roaming" difyctl <cmd>
Defensive patterns
Strategy: validation
Validate before calling
function assertWindowsCacheDir(): void {
if (process.platform !== 'win32') return
// appDataDir falls back APPDATA ?? LOCALAPPDATA, so either satisfies cacheDir
const appData = process.env.APPDATA ?? process.env.LOCALAPPDATA
if (appData === undefined || appData === '') {
throw new Error('set LOCALAPPDATA (or APPDATA) before running difyctl on Windows')
}
} Prevention
- Setting APPDATA satisfies both configDir and cacheDir — set it if you can only set one.
- Load the user profile for service-account tasks, or set the env vars explicitly.
- Don't rely on XDG_CACHE_HOME on Windows — the win32 factory ignores it.
When it happens
Trigger: Same broken-profile conditions as [54]: Windows service accounts, Task Scheduler without profile, minimal containers, non-interactive SSH — all with both APPDATA and LOCALAPPDATA missing. Because appDataDir falls back APPDATA→LOCALAPPDATA, the LOCALAPPDATA-only check in the message never actually runs independently.
Common situations: Identical to [54]: stripped Windows environments, SYSTEM account, containers, CI without profile load.
Related errors
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/08fc6ed401f8ecd1.
Report an issue: GitHub.
Appendix: source
Thrown at cli/src/sys/index.ts:107
}),
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,
})
export function resolvePlatform(): Platform {
return (platformImpls[platform()] ?? defaultPlatformFactory)()
}
View on GitHub (pinned to ef8544b173)