different-ai/openwork · error · EnvStoreReadError
Environment variable store is invalid JSON
Error message
Environment variable store is invalid JSON
What it means
Error raised when the server's environment variable store file exists but its contents are not valid JSON. Typically caused by manual edits, corrupted writes, or an incompatible serialization format in the persisted env store. Resolution is to fix or restore the JSON in the store file (or delete it so a fresh store is created); the server refuses to load the file to avoid silently dropping stored variables.
Source
Thrown at apps/server/src/env-file.ts:96
): Promise<EnvStoreFile> {
if (!(await exists(path))) {
return emptyStore();
}
let raw = "";
try {
raw = await readFile(path, "utf8");
} catch (error) {
if ((error as { code?: string }).code === "ENOENT") return emptyStore();
if (options.tolerateInvalid) return emptyStore();
throw new EnvStoreReadError("Environment variable store could not be read");
}
let parsed: Partial<EnvStoreFile>;
try {
parsed = JSON.parse(raw) as Partial<EnvStoreFile>;
} catch {
if (options.tolerateInvalid) return emptyStore();
throw new EnvStoreReadError("Environment variable store is invalid JSON");
}
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.variables)) {
if (options.tolerateInvalid) return emptyStore();
throw new EnvStoreReadError("Environment variable store has an invalid format");
}
const variables = parsed.variables
.map(parseRecord)
.filter((entry): entry is EnvRecord => Boolean(entry));
return {
schemaVersion: typeof parsed.schemaVersion === "number" ? parsed.schemaVersion : 1,
updatedAt: typeof parsed.updatedAt === "number" ? parsed.updatedAt : Date.now(),
variables,
};
}
async function writeStore(path: string, variables: EnvRecord[]): Promise<void> {View on GitHub (pinned to 2b7df46e8a)
Solutions
- Validate the file with JSON.parse (or jq) to see the syntax error and fix it by hand
- Delete/rename the corrupt file and re-add the variables via the API so a clean store is written
- Set tolerateInvalid if the caller treats a corrupt store as empty and should recover automatically
- Back up the corrupt file before deleting to recover any variable values manually
Example fix
// before
cat store.json # {"variables":[{"key":"A", <- truncated
// after
mv store.json store.json.bak # next read creates an empty valid store
# or: jq . store.json to locate and fix the syntax error Defensive patterns
Strategy: fallback
Validate before calling
let parsed; try { parsed = JSON.parse(raw); } catch { return emptyStore(); } Type guard
function looksLikeEnvStore(v: unknown): boolean { return typeof v === "object" && v !== null && Array.isArray((v as any).variables); } Try / catch
try { return await readStore(path, { tolerateInvalid: true }); } catch { return emptyStore(); } Prevention
- Use tolerateInvalid for read-only/cached reads
- Write atomically to avoid truncated files
- Keep a backup of the last valid store
When it happens
Trigger: ensureLoaded/store call readStore on a file whose contents are not valid JSON (truncated write, manual edits, wrong file configured).
Common situations: Crash or power loss mid-write left a truncated file; user hand-edited the file and left a syntax error; a different (non-JSON) file is at the configured path.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- ${result}
- Failed to write .opencode/openwork.json
- invalid_json
- invalid_plugin_manifest
- den_request_invalid_json
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/5d628ac07836e262.
Report an issue: GitHub.