{"record":{"id":"3b2895e28a39810f","repo":"different-ai/openwork","slug":"settings-environment-validation-duplicate","errorCode":"settings.environment.validation_duplicate","errorMessage":"t(\"settings.environment.validation_duplicate\")","messagePattern":"t\\(\"settings\\.environment\\.validation_duplicate\"\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/app/src/react-app/domains/settings/pages/environment-variable-provider.tsx","lineNumber":155,"sourceCode":"  const { mutate: modifyAsync, isPending: isModifying, reset: resetModify, error: modifyError } = useMutation({\n    mutationFn: async (nextEditor: EnvironmentEditorDraft) => {\n      if (!client) {\n        throw new Error(t(\"app.unknown_error\"));\n      }\n\n      const keyError = validateKey(nextEditor.key);\n\n      if (keyError) {\n        throw new Error(keyError);\n      }\n\n      const key = nextEditor.key.trim();\n      const existingItems = queryClient.getQueryData<{ items: EnvironmentVariableItem[] }>(\n        environmentUserEnvQueryKey(runtimeKey),\n      )?.items;\n\n      if (nextEditor.mode === \"add\" && existingItems?.some((item) => item.key === key)) {\n        throw new Error(t(\"settings.environment.validation_duplicate\"));\n      }\n\n      return client.upsertUserEnv([{ key, value: nextEditor.value }]);\n    },\n    onSuccess: async () => {\n      markChangesPending();\n\n      await queryClient.invalidateQueries({\n        queryKey: environmentUserEnvQueryKey(runtimeKey),\n      });\n    },\n  }); \n\n  const { mutate: removeAsync, isPending: isRemoving, reset: resetRemove, error: removeError } = useMutation({\n    mutationFn: async (key: string) => {\n      if (!client) {\n        throw new Error(t(\"app.unknown_error\"));\n      }","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/different-ai/openwork/blob/2b7df46e8ae1517d64c896c7793d2d52ec845669/apps/app/src/react-app/domains/settings/pages/environment-variable-provider.tsx#L137-L173","documentation":"When adding an environment variable, the mutation checks the cached env items (React Query cache for environmentUserEnvQueryKey) for a duplicate key and throws the localized \"settings.environment.validation_duplicate\" error if one already exists, preventing a conflicting upsert in \"add\" mode.","triggerScenarios":"modifyAsync with mode === \"add\" and a key that already exists in the current environment variable list for this runtime.","commonSituations":"Trying to add a variable like \"PATH\" or \"NODE_ENV\" that already exists; stale list vs. cache mismatch confusion; re-submitting a form after a previous successful add.","solutions":["Use edit/update mode for the existing entry instead of add","Pick a unique key name not present in the list","Refresh the environment variable list so the cache reflects current server state, then retry"],"exampleFix":"// before\nmode: \"add\", key: \"DEBUG\"\n// after (key exists)\nmode: \"edit\", key: \"DEBUG\", value: newValue","handlingStrategy":"validation","validationCode":"const items = queryClient.getQueryData<{ items: EnvironmentVariableItem[] }>(\n  environmentUserEnvQueryKey(runtimeKey),\n)?.items ?? [];\nif (mode === \"add\" && items.some(i => i.key === key.trim())) {\n  showDuplicateError();\n  return;\n}\nmodifyAsync(draft);","typeGuard":null,"tryCatchPattern":"try {\n  modifyAsync(draft);\n} catch (e) {\n  if (e.message.includes(\"validation_duplicate\")) highlightExistingRow(draft.key);\n  else throw e;\n}","preventionTips":["Check the existing list before choosing an add key","Refresh the env list cache before add operations","Use edit mode for existing keys"],"tags":["validation","duplicate-key","environment-variables"],"backgroundTag":"duplicate-key-conflict","analyzedSha":"2b7df46e8ae1517d64c896c7793d2d52ec845669","analyzedAt":"2026-09-01T07:59:23.713Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}