{"record":{"id":"4f06fa76d3f752b6","repo":"different-ai/openwork","slug":"invalid-env-key","errorCode":"invalid_env_key","errorMessage":"invalid_env_key","messagePattern":"invalid_env_key","errorType":"validation","errorClass":"InvalidEnvKeyError","httpStatus":null,"severity":"error","filePath":"apps/server/src/env-file.ts","lineNumber":203,"sourceCode":"      () => {},\n      () => {},\n    );\n    return run;\n  }\n\n  async list(): Promise<EnvRecord[]> {\n    await this.ensureLoaded();\n    return this.variables.slice();\n  }\n\n  async upsertMany(entries: EnvEntry[]): Promise<void> {\n    return this.enqueueMutation(async () => {\n      await this.ensureLoaded();\n      const now = Date.now();\n      const next = new Map(this.variables.map((entry) => [entry.key, entry] as const));\n      for (const entry of entries) {\n        if (!isValidEnvKey(entry.key)) {\n          throw new InvalidEnvKeyError(entry.key, \"invalid_env_key\");\n        }\n        if (isReservedEnvKey(entry.key)) {\n          throw new InvalidEnvKeyError(entry.key, \"reserved_env_key\");\n        }\n        next.set(entry.key, { key: entry.key, value: entry.value, updatedAt: now });\n      }\n      const nextVariables = Array.from(next.values()).sort((a, b) => a.key.localeCompare(b.key));\n      await writeStore(this.path, nextVariables);\n      this.variables = nextVariables;\n    });\n  }\n\n  async delete(key: string): Promise<boolean> {\n    return this.enqueueMutation(async () => {\n      await this.ensureLoaded();\n      const before = this.variables.length;\n      const nextVariables = this.variables.filter((entry) => entry.key !== key);\n      if (nextVariables.length === before) return false;","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/server/src/env-file.ts#L185-L221","documentation":"upsertMany validates each key with isValidEnvKey before persisting and throws InvalidEnvKeyError (code invalid_env_key) when a key is not a legal environment-variable name (typically /^[A-Za-z_][A-Za-z0-9_]*$/ style).","triggerScenarios":"Calling the env-store upsert API with keys containing hyphens, dots, spaces, leading digits, lowercase is fine but empty strings, or non-ASCII characters are not.","commonSituations":"Binding UI input straight through without validation; deriving keys from filenames or package names (my-app, foo.bar); copying shell var names with a leading digit like 1PASSWORD.","solutions":["Rename the key to a valid identifier: uppercase letters, digits, underscores only, not starting with a digit","Sanitize/normalize keys on the client (e.g. replace non-alphanumerics with underscores) before submitting","Reject invalid keys in the UI at input time so users never submit them"],"exampleFix":"// before\nawait envStore.upsertMany([{ key: \"MY-APP-TOKEN\", value: \"x\" }]);\n// after\nawait envStore.upsertMany([{ key: \"MY_APP_TOKEN\", value: \"x\" }]);","handlingStrategy":"validation","validationCode":"const bad = entries.filter(e => !/^[A-Za-z_][A-Za-z0-9_]*$/.test(e.key)); if (bad.length) throw new Error(`invalid keys: ${bad.map(b => b.key).join(\",\")}`);","typeGuard":"const isEnvKey = (k: string): k is string => /^[A-Za-z_][A-Za-z0-9_]*$/.test(k);","tryCatchPattern":"try { await envStore.upsertMany(entries); } catch (e) { if (e instanceof InvalidEnvKeyError) { return { skipped: e.key, reason: e.code }; } throw e; }","preventionTips":["Sanitize keys in one shared helper","Reject invalid keys at UI input","Document allowed key format"],"tags":["validation","env-vars","naming"],"backgroundTag":"invalid-env-var-name","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}