different-ai/openwork · error

keyError (i18n validation message returned by validateKey)

Error message

keyError (i18n validation message returned by validateKey)

What it means

The modify mutation validates the environment variable key with validateKey before persisting. If the key is invalid (empty, contains illegal characters, etc.), the returned i18n message is thrown as the mutation error so the UI surfaces it next to the form.

Source

Thrown at apps/app/src/react-app/domains/settings/pages/environment-variable-provider.tsx:146

  const markChangesPending = useCallback(() => {
    clearOpenworkEnvSystemContextCache();
    queryClient.setQueryData(["settings", "environment", "pending-changes", runtimeKey], true);
    resetApply();
    client?.setUserEnvPendingChanges(true, runtimeKey).catch(() => undefined);

    toast.info(t("settings.environment.restart_required"));
  }, [client, resetApply, queryClient, runtimeKey]);

  const { mutate: modifyAsync, isPending: isModifying, reset: resetModify, error: modifyError } = useMutation({
    mutationFn: async (nextEditor: EnvironmentEditorDraft) => {
      if (!client) {
        throw new Error(t("app.unknown_error"));
      }

      const keyError = validateKey(nextEditor.key);

      if (keyError) {
        throw new Error(keyError);
      }

      const key = nextEditor.key.trim();
      const existingItems = queryClient.getQueryData<{ items: EnvironmentVariableItem[] }>(
        environmentUserEnvQueryKey(runtimeKey),
      )?.items;

      if (nextEditor.mode === "add" && existingItems?.some((item) => item.key === key)) {
        throw new Error(t("settings.environment.validation_duplicate"));
      }

      return client.upsertUserEnv([{ key, value: nextEditor.value }]);
    },
    onSuccess: async () => {
      markChangesPending();

      await queryClient.invalidateQueries({
        queryKey: environmentUserEnvQueryKey(runtimeKey),

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Correct the key to a valid identifier (typically [A-Za-z_][A-Za-z0-9_]*)
  2. Inspect validateKey's rules in the codebase and match them
  3. Trim whitespace from the key before submitting

Example fix

// before
key: "MY VAR"
// after
key: "MY_VAR"
Defensive patterns

Strategy: validation

Validate before calling

const keyError = validateKey(key);
if (keyError) {
  setFieldError("key", keyError);
  return;
}
modifyAsync({ key, value, mode });

Type guard

const isValidEnvKey = (k: string) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(k.trim());

Try / catch

try {
  modifyAsync(draft);
} catch (e) {
  setFieldError("key", e.message);
}

Prevention

When it happens

Trigger: Calling modifyAsync with a draft whose key fails validateKey — e.g. empty key, whitespace-only key, or a key containing characters not allowed in environment variable names (spaces, '=', special symbols).

Common situations: Typing an invalid env var name like "MY VAR" or "PATH=extra"; clearing the key field then saving; pasting a line from a .env file including "KEY=value" into the key input.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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