diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py
index 0aea72be1e2..98464d3a127 100644
--- a/litellm/proxy/_types.py
+++ b/litellm/proxy/_types.py
@@ -1216,7 +1216,7 @@ class GenerateKeyRequest(KeyRequestBase):
organization_id: str | None = None
project_id: str | None = None
- @field_validator("team_id", "organization_id", mode="before")
+ @field_validator("team_id", "organization_id", "project_id", mode="before")
@classmethod
def treat_cleared_id_as_unset(cls, v: object) -> object:
if v == "":
diff --git a/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py
index 68704f476b5..7954a4693cc 100644
--- a/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py
+++ b/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py
@@ -17505,6 +17505,18 @@ def test_generate_key_request_blank_team_id_is_personal():
assert GenerateKeyRequest(team_id="team-1").team_id == "team-1"
+def test_generate_key_request_blank_organization_and_project_id_are_unset():
+ from litellm.proxy._types import RegenerateKeyRequest
+
+ cleared = GenerateKeyRequest(organization_id="", project_id="")
+ assert cleared.organization_id is None
+ assert cleared.project_id is None
+ assert "organization_id" not in cleared.model_dump(exclude_none=True)
+ assert RegenerateKeyRequest(organization_id="").organization_id is None
+ assert GenerateKeyRequest(organization_id="org-1", project_id="proj-1").organization_id == "org-1"
+ assert GenerateKeyRequest(organization_id="org-1", project_id="proj-1").project_id == "proj-1"
+
+
def test_key_request_blank_organization_id_is_unset():
from litellm.proxy._types import RegenerateKeyRequest, UpdateKeyRequest
diff --git a/ui/litellm-dashboard/src/components/common_components/OrganizationDropdown.test.tsx b/ui/litellm-dashboard/src/components/common_components/OrganizationDropdown.test.tsx
index e0b2b897b36..524ec6a715e 100644
--- a/ui/litellm-dashboard/src/components/common_components/OrganizationDropdown.test.tsx
+++ b/ui/litellm-dashboard/src/components/common_components/OrganizationDropdown.test.tsx
@@ -58,6 +58,17 @@ describe("OrganizationDropdown", () => {
expect(onChange.mock.calls[0][0]).toBe("org-1");
});
+ it("emits null, never the empty string, when the selection is cleared", async () => {
+ const onChange = vi.fn();
+ const user = userEvent.setup();
+ render();
+
+ await user.click(screen.getByRole("button", { name: "Clear" }));
+
+ expect(onChange).toHaveBeenCalledTimes(1);
+ expect(onChange).toHaveBeenCalledWith(null);
+ });
+
it("should filter options by organization id", async () => {
const user = userEvent.setup();
render();
diff --git a/ui/litellm-dashboard/src/components/common_components/OrganizationDropdown.tsx b/ui/litellm-dashboard/src/components/common_components/OrganizationDropdown.tsx
index 8da35ecd02e..663028b2d92 100644
--- a/ui/litellm-dashboard/src/components/common_components/OrganizationDropdown.tsx
+++ b/ui/litellm-dashboard/src/components/common_components/OrganizationDropdown.tsx
@@ -5,7 +5,7 @@ import { Organization } from "../networking";
interface OrganizationDropdownProps {
organizations?: Organization[] | null;
value?: string;
- onChange?: (value: string) => void;
+ onChange?: (value: string | null) => void;
disabled?: boolean;
loading?: boolean;
style?: React.CSSProperties;
@@ -32,7 +32,7 @@ const OrganizationDropdown: React.FC = ({
sublabel: org.organization_id,
}))}
value={value}
- onValueChange={(organizationId) => onChange?.(organizationId)}
+ onValueChange={(organizationId) => onChange?.(organizationId || null)}
placeholder={placeholder}
emptyText={loading ? "Loading organizations…" : "No organizations found"}
disabled={disabled}
diff --git a/ui/litellm-dashboard/src/components/organisms/create_key_button.tsx b/ui/litellm-dashboard/src/components/organisms/create_key_button.tsx
index 5749541dcea..ee3a88acba0 100644
--- a/ui/litellm-dashboard/src/components/organisms/create_key_button.tsx
+++ b/ui/litellm-dashboard/src/components/organisms/create_key_button.tsx
@@ -587,9 +587,9 @@ const CreateKey: React.FC = ({ team, teams, data, addKey, autoOp
}
};
- const changeOrganization = (write: FieldWrite) => (orgId: string) => {
- write(orgId || undefined);
- setSelectedOrganizationId(orgId || null);
+ const changeOrganization = (write: FieldWrite) => (orgId: string | null) => {
+ write(orgId ?? undefined);
+ setSelectedOrganizationId(orgId);
// Clear team and project when org changes
setSelectedCreateKeyTeam(null);
setSelectedProjectId(null);
diff --git a/ui/litellm-dashboard/src/components/templates/key_edit_view.tsx b/ui/litellm-dashboard/src/components/templates/key_edit_view.tsx
index 3e772fd0e9b..1330be2788b 100644
--- a/ui/litellm-dashboard/src/components/templates/key_edit_view.tsx
+++ b/ui/litellm-dashboard/src/components/templates/key_edit_view.tsx
@@ -303,9 +303,9 @@ export function KeyEditView({
}
};
- const handleOrganizationChange = (setField: (value: string | null) => void, orgId: string | undefined) => {
- setField(orgId || null);
- setSelectedOrganizationId(orgId || null);
+ const handleOrganizationChange = (setField: (value: string | null) => void, orgId: string | null) => {
+ setField(orgId);
+ setSelectedOrganizationId(orgId);
form.setValue("team_id", undefined);
};