{"record":{"id":"af8b56189b0399c7","repo":"different-ai/openwork","slug":"environment-variable-store-could-not-be-read","errorCode":null,"errorMessage":"Environment variable store could not be read","messagePattern":"Environment variable store could not be read","errorType":"error_code","errorClass":"EnvStoreReadError","httpStatus":null,"severity":"error","filePath":"apps/server/src/env-file.ts","lineNumber":88,"sourceCode":"\nfunction emptyStore(): EnvStoreFile {\n  return { schemaVersion: 1, updatedAt: Date.now(), variables: [] };\n}\n\nasync function readStore(\n  path: string,\n  options: { tolerateInvalid?: boolean } = {},\n): Promise<EnvStoreFile> {\n  if (!(await exists(path))) {\n    return emptyStore();\n  }\n  let raw = \"\";\n  try {\n    raw = await readFile(path, \"utf8\");\n  } catch (error) {\n    if ((error as { code?: string }).code === \"ENOENT\") return emptyStore();\n    if (options.tolerateInvalid) return emptyStore();\n    throw new EnvStoreReadError(\"Environment variable store could not be read\");\n  }\n\n  let parsed: Partial<EnvStoreFile>;\n  try {\n    parsed = JSON.parse(raw) as Partial<EnvStoreFile>;\n  } catch {\n    if (options.tolerateInvalid) return emptyStore();\n    throw new EnvStoreReadError(\"Environment variable store is invalid JSON\");\n  }\n\n  if (!parsed || typeof parsed !== \"object\" || !Array.isArray(parsed.variables)) {\n    if (options.tolerateInvalid) return emptyStore();\n    throw new EnvStoreReadError(\"Environment variable store has an invalid format\");\n  }\n\n  const variables = parsed.variables\n    .map(parseRecord)\n    .filter((entry): entry is EnvRecord => Boolean(entry));","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/server/src/env-file.ts#L70-L106","documentation":"readStore reads the env-var store file and throws EnvStoreReadError when the file exists but cannot be read (any error other than ENOENT), or when tolerateInvalid is false and callers should not silently get an empty store.","triggerScenarios":"ensureLoaded/store call readStore while the store file exists but is unreadable: permission denied, EACCES, EISDIR (path is a directory), or an I/O error; ENOENT is tolerated (returns empty store).","commonSituations":"Store file created by another user/root with restrictive permissions; wrong path configured pointing at a directory; disk I/O failure; read-only filesystem mount.","solutions":["Check file permissions on the env store file and fix ownership/chmod so the server process can read it","Verify the configured store path points at a regular file, not a directory","If the data is disposable, delete the corrupted/unreadable file so the next read creates a fresh store (ENOENT path)","Run the server with the same user that owns the store file"],"exampleFix":"// before\nstore.json -> owned by root, mode 600, server runs as \"app\"\n// after\nsudo chown app:app store.json && chmod 600 store.json","handlingStrategy":"fallback","validationCode":"try { await stat(path); } catch (e) { if (e.code !== \"ENOENT\") warn(\"store file unreadable: \" + e.code); }","typeGuard":null,"tryCatchPattern":"try { return await readStore(path, { tolerateInvalid: false }); } catch { return { variables: [] }; }","preventionTips":["Pre-create the store file with safe permissions at install time","Keep server data dirs owned by the server user","Monitor for non-ENOENT fs errors"],"tags":["filesystem","permissions","env-store"],"backgroundTag":"file-read-permission-denied","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}