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

  1. Validate the file with JSON.parse (or jq) to see the syntax error and fix it by hand
  2. Delete/rename the corrupt file and re-add the variables via the API so a clean store is written
  3. Set tolerateInvalid if the caller treats a corrupt store as empty and should recover automatically
  4. 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

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

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/5d628ac07836e262. Report an issue: GitHub.