marktext/marktext · critical · Error
Can not load static preference.json file
Error message
Can not load static preference.json file
What it means
Thrown by Preferences.init() when defaultSettings is still null after the try/catch that reads and JSON.parses static/preference.json. The catch logs but leaves defaultSettings null, so the subsequent guard converts any read/parse failure of the bundled preference.json into a fatal startup error.
Source
Thrown at packages/desktop/src/main/preferences/index.ts:86
// Set best theme on first application start.
if (nativeTheme.shouldUseDarkColors) {
defaultSettings!.theme = 'dark'
}
// Set system language on first application start
if (!this.hasPreferencesFile) {
const systemLanguage = this._getSystemLanguage()
if (systemLanguage) {
defaultSettings!.language = systemLanguage
}
}
} catch (err) {
log.error(err)
}
if (!defaultSettings) {
throw new Error('Can not load static preference.json file')
}
// I don't know why `this.store.size` is 3 when first load, so I just check file existed.
if (!this.hasPreferencesFile) {
this.store.set(defaultSettings)
} else {
// Because `this.getAll()` will return a plainObject, so we can not use `hasOwnProperty` method
// const plainObject = () => Object.create(null)
const userSetting = this.getAll() as Record<string, unknown>
// Update outdated settings
const requiresUpdate = !hasSameKeys(defaultSettings, userSetting)
const userSettingKeys = Object.keys(userSetting)
const defaultSettingKeys = Object.keys(defaultSettings)
if (requiresUpdate) {
// TODO(fxha): For performance reasons, we should try to replace 'electron-store' because
// it does multiple blocking I/O calls when changing entries. There is no transaction or
// async I/O available. The core reason we changed to it was JSON scheme validation.View on GitHub (pinned to e52106fd1c)
Solutions
- Rebuild static assets: `pnpm run build:unpack` and confirm preference.json is emitted under out/resources or static/.
- Verify global.__static is set correctly in main/config.js and points at the directory containing preference.json.
- Ship a hard-coded fallback default settings object so a missing file does not crash startup.
- Differentiate the error: log whether readFileSync or JSON.parse failed to speed diagnosis.
Example fix
// before
try {
defaultSettings = JSON.parse(fs.readFileSync(this.staticPath, { encoding: 'utf8' }) || '{}')
} catch (err) { log.error(err) }
if (!defaultSettings) throw new Error('Can not load static preference.json file')
// after — bundled fallback
try {
defaultSettings = JSON.parse(fs.readFileSync(this.staticPath, { encoding: 'utf8' }) || '{}')
} catch (err) {
log.error('Failed to load preference.json, using bundled defaults', err)
defaultSettings = BUNDLED_DEFAULT_SETTINGS
} Defensive patterns
Strategy: fallback
Validate before calling
import fs from 'fs'
function preferenceJsonReadable(p: string): boolean {
try { return fs.existsSync(p) && fs.readFileSync(p, 'utf8').trim().length > 0 }
catch { return false }
} Try / catch
try { /* load preference.json */ }
catch (e) { log.error('preference.json unreadable, using bundled defaults', e) } Prevention
- Bundle a default-settings object so a missing preference.json cannot crash startup.
- Verify electron-vite copies static/preference.json into resources in the build pipeline.
- Differentiate readFileSync vs JSON.parse failures in the log.
- Add a smoke test that boots the main process with preference.json absent.
When it happens
Trigger: fs.readFileSync(this.staticPath) fails (file missing — global.__static points at an unbuilt resources dir); JSON.parse fails (corrupt preference.json shipped in the build); the file is empty so parsing '{}' fallback is bypassed because readFileSync threw first.
Common situations: A production build where electron-vite did not copy static/preference.json into resources. A dev run with global.__static misconfigured. A manually corrupted preference.json in the package. This blocks the entire app from starting.
Related errors
- Unsupported uploader: ${currentUploader}
- Translation file not found for language: ${language}
- No pages registered for tab "${tab}"
- failed to load docs index
AI-assisted analysis of marktext/marktext@e52106fd1c (2026-08-12).
Data as JSON: /api/errors/0513edb844b365f0.
Report an issue: GitHub.