From a074d1d68b4d088e9b1040a60bf522e89db9b53f Mon Sep 17 00:00:00 2001 From: Yuneng Jiang Date: Fri, 27 Mar 2026 16:45:12 -0700 Subject: [PATCH] [Infra] Mirror litellm_table_patch source changes (no binaries) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cherry-pick source-only changes from litellm_table_patch, excluding build artifacts from the incident response period. - Remove destructive DROP COLUMN migration (20260311180521_schema_sync) - Remove now-unnecessary restore migration (20260327232350) - Bump litellm-proxy-extras 0.4.60 → 0.4.61 - Add regression test to block future DROP COLUMN migrations - Fix double error handling in getTeamPermissionsCall Co-Authored-By: Claude Opus 4.6 (1M context) --- .../20260311180521_schema_sync/migration.sql | 11 ---------- .../migration.sql | 14 ------------- litellm-proxy-extras/pyproject.toml | 4 ++-- poetry.lock | 8 +++---- pyproject.toml | 2 +- requirements.txt | 2 +- .../test_litellm_proxy_extras_utils.py | 21 +++++++++++++++++++ .../src/components/networking.tsx | 5 ++--- 8 files changed, 31 insertions(+), 36 deletions(-) delete mode 100644 litellm-proxy-extras/litellm_proxy_extras/migrations/20260311180521_schema_sync/migration.sql delete mode 100644 litellm-proxy-extras/litellm_proxy_extras/migrations/20260327232350_restore_mcp_byom_fields/migration.sql diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260311180521_schema_sync/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260311180521_schema_sync/migration.sql deleted file mode 100644 index 84eb70ce097..00000000000 --- a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260311180521_schema_sync/migration.sql +++ /dev/null @@ -1,11 +0,0 @@ --- DropIndex -DROP INDEX IF EXISTS "LiteLLM_MCPServerTable_approval_status_idx"; - --- AlterTable -ALTER TABLE "LiteLLM_MCPServerTable" DROP COLUMN IF EXISTS "approval_status", -DROP COLUMN IF EXISTS "review_notes", -DROP COLUMN IF EXISTS "reviewed_at", -DROP COLUMN IF EXISTS "source_url", -DROP COLUMN IF EXISTS "submitted_at", -DROP COLUMN IF EXISTS "submitted_by"; - diff --git a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260327232350_restore_mcp_byom_fields/migration.sql b/litellm-proxy-extras/litellm_proxy_extras/migrations/20260327232350_restore_mcp_byom_fields/migration.sql deleted file mode 100644 index db965192512..00000000000 --- a/litellm-proxy-extras/litellm_proxy_extras/migrations/20260327232350_restore_mcp_byom_fields/migration.sql +++ /dev/null @@ -1,14 +0,0 @@ --- AlterTable: Restore BYOM lifecycle fields to LiteLLM_MCPServerTable --- These were dropped in 20260311180521_schema_sync due to schema drift. --- The proxy schema (source of truth) retained them. -ALTER TABLE "LiteLLM_MCPServerTable" - ADD COLUMN IF NOT EXISTS "source_url" TEXT, - ADD COLUMN IF NOT EXISTS "approval_status" TEXT DEFAULT 'active', - ADD COLUMN IF NOT EXISTS "submitted_by" TEXT, - ADD COLUMN IF NOT EXISTS "submitted_at" TIMESTAMP(3), - ADD COLUMN IF NOT EXISTS "reviewed_at" TIMESTAMP(3), - ADD COLUMN IF NOT EXISTS "review_notes" TEXT; - --- CreateIndex -CREATE INDEX IF NOT EXISTS "LiteLLM_MCPServerTable_approval_status_idx" - ON "LiteLLM_MCPServerTable"("approval_status"); diff --git a/litellm-proxy-extras/pyproject.toml b/litellm-proxy-extras/pyproject.toml index 14253ad15db..f03cdf61c2a 100644 --- a/litellm-proxy-extras/pyproject.toml +++ b/litellm-proxy-extras/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "litellm-proxy-extras" -version = "0.4.60" +version = "0.4.61" description = "Additional files for the LiteLLM Proxy. Reduces the size of the main litellm package." authors = ["BerriAI"] readme = "README.md" @@ -22,7 +22,7 @@ requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" [tool.commitizen] -version = "0.4.60" +version = "0.4.61" version_files = [ "pyproject.toml:version", "../requirements.txt:litellm-proxy-extras==", diff --git a/poetry.lock b/poetry.lock index b9eba6e0a30..958e0ac65b8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3219,15 +3219,15 @@ files = [ [[package]] name = "litellm-proxy-extras" -version = "0.4.60" +version = "0.4.61" description = "Additional files for the LiteLLM Proxy. Reduces the size of the main litellm package." optional = true python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" groups = ["main"] markers = "extra == \"proxy\"" files = [ - {file = "litellm_proxy_extras-0.4.60-py3-none-any.whl", hash = "sha256:7abcc811f7430e4b24e7a8ba7186219a4845a955ae7a71d8822bd03fd9fc3393"}, - {file = "litellm_proxy_extras-0.4.60.tar.gz", hash = "sha256:1c122f2a7e0eb58fa4c6d8da9da82ac1fe2869de3510bcfade5c2932af202328"}, + {file = "litellm_proxy_extras-0.4.61-py3-none-any.whl", hash = "sha256:9bd1e57ef51972cacff52172ef5d70b0ff689f57f3d240877667301ab8f8590e"}, + {file = "litellm_proxy_extras-0.4.61.tar.gz", hash = "sha256:dce8e39b1547abf90d912ddd0f2a876beadf789d700ef04c165362d78ad56aee"}, ] [[package]] @@ -8009,4 +8009,4 @@ utils = ["numpydoc"] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4.0" -content-hash = "b4e3ee072f600fab9810024afdd550407d25733a9b6752476aa61826e33bc08e" +content-hash = "8dad0e86d75e574f12c57c9f32614b7b4ea2181e931874046d43a398aef1e998" diff --git a/pyproject.toml b/pyproject.toml index b2a446149e5..ced8c4eb712 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,7 +61,7 @@ boto3 = { version = "^1.40.76", optional = true } redisvl = {version = "^0.4.1", optional = true, markers = "python_version >= '3.9' and python_version < '3.14'"} mcp = {version = ">=1.25.0,<2.0.0", optional = true, python = ">=3.10"} a2a-sdk = {version = "^0.3.22", optional = true, python = ">=3.10"} -litellm-proxy-extras = {version = "^0.4.60", optional = true} +litellm-proxy-extras = {version = "^0.4.61", optional = true} rich = {version = "^13.7.1", optional = true} litellm-enterprise = {version = "0.1.35", optional = true} diskcache = {version = "^5.6.1", optional = true} diff --git a/requirements.txt b/requirements.txt index 7ce9ab04d2a..d9e188c6e64 100644 --- a/requirements.txt +++ b/requirements.txt @@ -57,7 +57,7 @@ grpcio>=1.75.0; python_version >= "3.14" sentry_sdk==2.21.0 # for sentry error handling detect-secrets==1.5.0 # Enterprise - secret detection / masking in LLM requests tzdata==2025.1 # IANA time zone database -litellm-proxy-extras==0.4.60 # for proxy extras - e.g. prisma migrations +litellm-proxy-extras==0.4.61 # for proxy extras - e.g. prisma migrations llm-sandbox==0.3.31 # for skill execution in sandbox ### LITELLM PACKAGE DEPENDENCIES python-dotenv==1.0.1 # for env diff --git a/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py b/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py index c1e3fd5072f..062748f3387 100644 --- a/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py +++ b/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py @@ -222,6 +222,27 @@ class TestMigrationSQLIdempotency: + "\n".join(violations) ) + _DROP_COLUMN_ALLOWLIST = { + "20250918083359_drop_spec_version_column_from_mcp_table", + "20260213170952_access_group_change_to_model_name", + "20260224203854_add_agent_object_permissions_table", + } + + def test_no_drop_column_statements(self, all_migrations): + """Migrations must not drop columns — dropping columns is destructive + and can break running application instances during rolling deploys.""" + violations = [] + for migration_name, sql in all_migrations: + if migration_name in self._DROP_COLUMN_ALLOWLIST: + continue + for line_num, line in enumerate(sql.splitlines(), 1): + if re.search(r"DROP\s+COLUMN", line, re.IGNORECASE): + violations.append(f" {migration_name}:{line_num}: {line.strip()}") + assert not violations, ( + "DROP COLUMN found in migrations (destructive, not allowed):\n" + + "\n".join(violations) + ) + def test_drop_index_uses_if_exists(self, all_migrations): """DROP INDEX statements must use IF EXISTS""" violations = [] diff --git a/ui/litellm-dashboard/src/components/networking.tsx b/ui/litellm-dashboard/src/components/networking.tsx index c33ca700fdf..2e8518d00a6 100644 --- a/ui/litellm-dashboard/src/components/networking.tsx +++ b/ui/litellm-dashboard/src/components/networking.tsx @@ -7288,12 +7288,11 @@ export const getTeamPermissionsCall = async (accessToken: string, teamId: string if (!response.ok) { const errorData = await response.json(); const errorMessage = deriveErrorMessage(errorData); - handleError(errorMessage); - throw new Error(errorMessage); + console.error("Available permissions fetch failed:", errorMessage); + return { all_available_permissions: [], team_member_permissions: [] }; } const data = await response.json(); - console.log("Team permissions response:", data); return data; } catch (error) { console.error("Failed to get team permissions:", error);