You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polaris.apache.org by yz...@apache.org on 2026/10/20 02:06:45 UTC

(polaris) branch main updated: Update OpenAPI spec from 3.0.x to 3.1.x (#5819)

This is an automated email from the ASF dual-hosted git repository.

MonkeyCanCode pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git


The following commit(s) were added to refs/heads/main by this push:
     new 5fafc67a83 Update OpenAPI spec from 3.0.x to 3.1.x (#5819)
5fafc67a83 is described below

commit 5fafc67a832a8900fefb399abc00549d864470d6
Author: Yong Zheng <yo...@gmail.com>
AuthorDate: Mon Oct 19 21:06:40 2026 -0500

    Update OpenAPI spec from 3.0.x to 3.1.x (#5819)
---
 .github/renovate.json5                             |  5 ----
 .github/workflows/ci.yml                           |  2 ++
 Makefile                                           |  9 ++++++
 api/iceberg-service/build.gradle.kts               |  8 ++---
 api/management-model/build.gradle.kts              |  8 ++---
 api/management-service/build.gradle.kts            |  8 ++---
 api/polaris-catalog-service/build.gradle.kts       |  8 ++---
 client/python/apache_polaris/cli/command/views.py  |  7 ++---
 client/python/generate_clients.py                  |  2 +-
 client/python/pyproject.toml                       |  6 ++--
 client/python/tests/cli_test_utils.py              |  1 +
 client/python/tests/test_views_command.py          |  7 +----
 client/python/uv.lock                              |  8 ++---
 extensions/semantic-models/build.gradle.kts        |  8 ++---
 gradle/libs.versions.toml                          |  2 +-
 .../generated/bundled-polaris-catalog-service.yaml | 34 ++++++++++++----------
 spec/iceberg-rest-catalog-open-api.yaml            | 16 ++++------
 spec/polaris-catalog-apis/policy-apis.yaml         |  4 +--
 spec/polaris-catalog-service.yaml                  |  2 +-
 spec/polaris-management-service.yml                |  2 +-
 20 files changed, 70 insertions(+), 77 deletions(-)

diff --git a/.github/renovate.json5 b/.github/renovate.json5
index ad207e8fe1..f3a7abd8a8 100644
--- a/.github/renovate.json5
+++ b/.github/renovate.json5
@@ -105,11 +105,6 @@
       ],
       enabled: false
     },
-    // Disable update for openapi-generator-cli due to our OpenAPI spec version
-    {
-      matchPackageNames: ["openapi-generator-cli"],
-      enabled: false
-    },
     // Disable update for python version
     {
       matchPackageNames: ["python"],
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2c7b379154..c53d063ce7 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -84,6 +84,8 @@ jobs:
           node-version: '24'
       - name: Renovate Configuration Validation
         run: npx --yes --package renovate renovate-config-validator --strict --no-global .github/renovate.json5
+      - name: Verify bundled OpenAPI spec is up to date
+        run: make spec-bundle-verify
       # Intentionally unpinned to always use the latest allowlist from the ASF.
       - uses: apache/infrastructure-actions/allowlist-check@main # zizmor: ignore[unpinned-uses]
 
diff --git a/Makefile b/Makefile
index 40b69c0684..d373a4dc1b 100644
--- a/Makefile
+++ b/Makefile
@@ -137,6 +137,15 @@ spec-bundle: ## Regenerate the bundled OpenAPI spec, license header included
 	@./spec/bundle.sh
 	@echo "--- Bundled OpenAPI spec regenerated ---"
 
+.PHONY: spec-bundle-verify
+spec-bundle-verify: spec-bundle ## Verify the bundled OpenAPI spec is up to date
+	@echo "--- Verifying bundled OpenAPI spec is up to date ---"
+	@if ! git diff --exit-code spec/generated/; then \
+		echo "ERROR: bundled OpenAPI spec is out of date. Please run 'make spec-bundle' and commit the changes."; \
+		exit 1; \
+	fi
+	@echo "--- Bundled OpenAPI spec is up to date ---"
+
 ##@ Polaris Client
 
 # Target to create the virtual environment directory
diff --git a/api/iceberg-service/build.gradle.kts b/api/iceberg-service/build.gradle.kts
index fd31486aee..110445742d 100644
--- a/api/iceberg-service/build.gradle.kts
+++ b/api/iceberg-service/build.gradle.kts
@@ -63,12 +63,12 @@ val generatedOpenApiSrcDir = project.layout.buildDirectory.dir("generated-openap
 openApiGenerate {
   // The OpenAPI generator does NOT resolve relative paths correctly against the Gradle project
   // directory
-  inputSpec = provider { specsDir.file("polaris-catalog-service.yaml").asFile.absolutePath }
+  inputSpec = specsDir.file("generated/bundled-polaris-catalog-service.yaml")
   generatorName = "jaxrs-resteasy"
-  outputDir = provider { generatedDir.get().asFile.absolutePath }
+  outputDir = generatedDir
   apiPackage = "org.apache.polaris.service.catalog.api"
-  ignoreFileOverride.set(provider { rootDir.file(".openapi-generator-ignore").asFile.absolutePath })
-  templateDir.set(provider { templatesDir.asFile.absolutePath })
+  ignoreFileOverride = rootDir.file(".openapi-generator-ignore")
+  templateDir = templatesDir
   removeOperationIdPrefix.set(true)
   globalProperties.put("apis", "CatalogApi,ConfigurationApi,OAuth2Api")
   globalProperties.put("models", "false")
diff --git a/api/management-model/build.gradle.kts b/api/management-model/build.gradle.kts
index 3e2f3120e7..9c9c2dc228 100644
--- a/api/management-model/build.gradle.kts
+++ b/api/management-model/build.gradle.kts
@@ -50,13 +50,13 @@ val generatedOpenApiSrcDir = project.layout.buildDirectory.dir("generated-openap
 openApiGenerate {
   // The OpenAPI generator does NOT resolve relative paths correctly against the Gradle project
   // directory
-  inputSpec = provider { specsDir.file("polaris-management-service.yml").asFile.absolutePath }
+  inputSpec = specsDir.file("polaris-management-service.yml")
   generatorName = "jaxrs-resteasy"
-  outputDir = provider { generatedDir.get().asFile.absolutePath }
+  outputDir = generatedDir
   modelPackage = "org.apache.polaris.core.admin.model"
-  ignoreFileOverride.set(provider { rootDir.file(".openapi-generator-ignore").asFile.absolutePath })
+  ignoreFileOverride = rootDir.file(".openapi-generator-ignore")
   removeOperationIdPrefix.set(true)
-  templateDir.set(provider { templatesDir.asFile.absolutePath })
+  templateDir = templatesDir
   globalProperties.put("apis", "false")
   globalProperties.put("models", "")
   globalProperties.put("apiDocs", "false")
diff --git a/api/management-service/build.gradle.kts b/api/management-service/build.gradle.kts
index eb8a06019e..56894811c4 100644
--- a/api/management-service/build.gradle.kts
+++ b/api/management-service/build.gradle.kts
@@ -59,14 +59,14 @@ val generatedOpenApiSrcDir = project.layout.buildDirectory.dir("generated-openap
 openApiGenerate {
   // The OpenAPI generator does NOT resolve relative paths correctly against the Gradle project
   // directory
-  inputSpec = provider { specsDir.file("polaris-management-service.yml").asFile.absolutePath }
+  inputSpec = specsDir.file("polaris-management-service.yml")
   generatorName = "jaxrs-resteasy"
-  outputDir = provider { generatedDir.get().asFile.absolutePath }
+  outputDir = generatedDir
   apiPackage = "org.apache.polaris.service.admin.api"
   modelPackage = "org.apache.polaris.core.admin.model"
-  ignoreFileOverride.set(provider { rootDir.file(".openapi-generator-ignore").asFile.absolutePath })
+  ignoreFileOverride = rootDir.file(".openapi-generator-ignore")
   removeOperationIdPrefix.set(true)
-  templateDir.set(provider { templatesDir.asFile.absolutePath })
+  templateDir = templatesDir
   globalProperties.put("apis", "")
   globalProperties.put("models", "false")
   globalProperties.put("apiDocs", "false")
diff --git a/api/polaris-catalog-service/build.gradle.kts b/api/polaris-catalog-service/build.gradle.kts
index 5475b71876..55cb12868f 100644
--- a/api/polaris-catalog-service/build.gradle.kts
+++ b/api/polaris-catalog-service/build.gradle.kts
@@ -93,14 +93,14 @@ val generatedOpenApiSrcDir = project.layout.buildDirectory.dir("generated-openap
 openApiGenerate {
   // The OpenAPI generator does NOT resolve relative paths correctly against the Gradle project
   // directory
-  inputSpec = provider { specsDir.file("polaris-catalog-service.yaml").asFile.absolutePath }
+  inputSpec = specsDir.file("generated/bundled-polaris-catalog-service.yaml")
   generatorName = "jaxrs-resteasy"
-  outputDir = provider { generatedDir.get().asFile.absolutePath }
+  outputDir = generatedDir
   apiPackage = "org.apache.polaris.service.catalog.api"
   modelPackage = "org.apache.polaris.service.types"
-  ignoreFileOverride.set(provider { rootDir.file(".openapi-generator-ignore").asFile.absolutePath })
+  ignoreFileOverride = rootDir.file(".openapi-generator-ignore")
   removeOperationIdPrefix.set(true)
-  templateDir.set(provider { templatesDir.asFile.absolutePath })
+  templateDir = templatesDir
   globalProperties.put("apis", "GenericTableApi,PolicyApi")
   globalProperties.put("models", models)
   globalProperties.put("apiDocs", "false")
diff --git a/client/python/apache_polaris/cli/command/views.py b/client/python/apache_polaris/cli/command/views.py
index b429d0d300..c5f6400a62 100644
--- a/client/python/apache_polaris/cli/command/views.py
+++ b/client/python/apache_polaris/cli/command/views.py
@@ -162,12 +162,9 @@ class ViewCommand(Command):
                 # SQL representations
                 print("\nRepresentations")
                 for representation in current_version.representations:
-                    unwrapped = representation.actual_instance
-                    if unwrapped is None:
-                        continue
-                    print(f"  {'Dialect:':<30} {unwrapped.dialect}")
+                    print(f"  {'Dialect:':<30} {representation.dialect}")
                     indented_sql = "\n".join(
-                        " " * 4 + line for line in unwrapped.sql.splitlines()
+                        " " * 4 + line for line in representation.sql.splitlines()
                     )
                     print("  SQL:")
                     print(indented_sql)
diff --git a/client/python/generate_clients.py b/client/python/generate_clients.py
index f667e7f33b..e3c1e2e95d 100644
--- a/client/python/generate_clients.py
+++ b/client/python/generate_clients.py
@@ -31,7 +31,7 @@ HEADER_DIR = CLIENT_DIR / "templates"
 SPEC_DIR = CLIENT_DIR / "spec"
 POLARIS_MANAGEMENT_SPEC = SPEC_DIR / "polaris-management-service.yml"
 ICEBERG_CATALOG_SPEC = SPEC_DIR / "iceberg-rest-catalog-open-api.yaml"
-POLARIS_CATALOG_SPEC = SPEC_DIR / "polaris-catalog-service.yaml"
+POLARIS_CATALOG_SPEC = SPEC_DIR / "generated" / "bundled-polaris-catalog-service.yaml"
 OPEN_API_GENERATOR_IGNORE = CLIENT_DIR / ".openapi-generator-ignore"
 
 # Open API Generator Configs
diff --git a/client/python/pyproject.toml b/client/python/pyproject.toml
index 94b03b6e80..2127fb84a2 100644
--- a/client/python/pyproject.toml
+++ b/client/python/pyproject.toml
@@ -58,8 +58,7 @@ dev = [
     "mypy>=2.4, <=2.4.0",
     "pyiceberg==0.12.0",
     "pre-commit==4.7.0",
-    # 7.12.0 is the latest version to use due to OpenAPI spec version we are using
-    "openapi-generator-cli==7.12.0",
+    "openapi-generator-cli==7.26.0",
     "pip-licenses-cli==4.1.0",
 ]
 
@@ -85,8 +84,7 @@ exclude = ["**/.keep"]
 path = "hatch_build.py"
 
 [build-system]
-# 7.12.0 is the latest version to use due to OpenAPI spec version we are using
-requires = ["hatchling", "openapi-generator-cli==7.12.0"]
+requires = ["hatchling", "openapi-generator-cli==7.26.0"]
 build-backend = "hatchling.build"
 
 [tool.uv]
diff --git a/client/python/tests/cli_test_utils.py b/client/python/tests/cli_test_utils.py
index a3379bc08b..df280cbbde 100644
--- a/client/python/tests/cli_test_utils.py
+++ b/client/python/tests/cli_test_utils.py
@@ -43,6 +43,7 @@ class CLITestBase(unittest.TestCase):
         client.api_client.configuration.username = None
         client.api_client.configuration.password = None
         client.api_client.configuration.access_token = None
+        client.api_client.configuration._polaris_catalog_base = None
         client.api_client.default_headers = {}
         return client
 
diff --git a/client/python/tests/test_views_command.py b/client/python/tests/test_views_command.py
index d196b2e1b3..3a473bc146 100644
--- a/client/python/tests/test_views_command.py
+++ b/client/python/tests/test_views_command.py
@@ -34,7 +34,6 @@ from apache_polaris.sdk.catalog.models import (
     Type,
     ViewHistoryEntry,
     ViewMetadata,
-    ViewRepresentation,
     ViewVersion,
 )
 
@@ -57,11 +56,7 @@ def _build_load_view_result(current_version_id: int = 1) -> LoadViewResult:
         summary={},
         default_namespace=["ns1"],
         representations=[
-            ViewRepresentation(
-                SQLViewRepresentation(
-                    type="sql", sql="SELECT id FROM t", dialect="spark"
-                )
-            )
+            SQLViewRepresentation(type="sql", sql="SELECT id FROM t", dialect="spark")
         ],
     )
     metadata = ViewMetadata(
diff --git a/client/python/uv.lock b/client/python/uv.lock
index 61eb81f1c9..e98c0d4864 100644
--- a/client/python/uv.lock
+++ b/client/python/uv.lock
@@ -57,7 +57,7 @@ requires-dist = [
 dev = [
     { name = "flake8", specifier = ">=4.0.0" },
     { name = "mypy", specifier = "<=2.4.0,>=2.4" },
-    { name = "openapi-generator-cli", specifier = "==7.12.0" },
+    { name = "openapi-generator-cli", specifier = "==7.26.0" },
     { name = "pip-licenses-cli", specifier = "==4.1.0" },
     { name = "pre-commit", specifier = "==4.7.0" },
     { name = "pyiceberg", specifier = "==0.12.0" },
@@ -770,11 +770,11 @@ wheels = [
 
 [[package]]
 name = "openapi-generator-cli"
-version = "7.12.0"
+version = "7.26.0"
 source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/8f5bb83112179efd887b60390e3b5fdbb38bd993965ef4ce88740d8a6f29/openapi_generator_cli-7.12.0.tar.gz", hash = "sha256:11dc4fd67fc7d839572ae8e29fb1dee5892195a7ac88b98e41a2cd8105e3250f", size = 27094673, upload-time = "2025-03-27T12:51:54.247Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/b3/be/1832670f038b324ef0cbbbe96b2bbf79b753fe07e0e00b48256784d71dc5/openapi_generator_cli-7.26.0.tar.gz", hash = "sha256:98e18e9a9e32f1f357595858526954542128bdace6a24c8cc7c8ebff8ca16e74", size = 30287266, upload-time = "2026-10-07T04:45:11.963Z" }
 wheels = [
-    { url = "https://files.pythonhosted.org/packages/9b/a8/23b4e7fca4e7015f461c2c520bc49b9b57a6635fd404dd77b0b6f917493e/openapi_generator_cli-7.12.0-py3-none-any.whl", hash = "sha256:cf97e0e40bacc66ca70963845e52b0c003aaab85da7f1d10cc25abf2f1c8bb6e", size = 27108048, upload-time = "2025-03-27T12:51:51.086Z" },
+    { url = "https://files.pythonhosted.org/packages/b6/fd/36deca16b2312ef5e3d5ee77ed1b1e3550c98dee60fffc76e16e25697149/openapi_generator_cli-7.26.0-py3-none-any.whl", hash = "sha256:e6305fbbf91aa41b3b7fcd8bf2124880ab0bb9e32efad95b3dfe71f9313d856c", size = 30301947, upload-time = "2026-10-07T04:45:07.017Z" },
 ]
 
 [[package]]
diff --git a/extensions/semantic-models/build.gradle.kts b/extensions/semantic-models/build.gradle.kts
index 4fb24a92e6..d6297b70b5 100644
--- a/extensions/semantic-models/build.gradle.kts
+++ b/extensions/semantic-models/build.gradle.kts
@@ -98,16 +98,16 @@ val generatedOpenApiSrcDir = project.layout.buildDirectory.dir("generated-openap
 openApiGenerate {
   // The OpenAPI generator does NOT resolve relative paths correctly against the Gradle project
   // directory
-  inputSpec = provider { specsDir.file("polaris-catalog-service.yaml").asFile.absolutePath }
+  inputSpec = specsDir.file("generated/bundled-polaris-catalog-service.yaml")
   generatorName = "jaxrs-resteasy"
-  outputDir = provider { generatedDir.get().asFile.absolutePath }
+  outputDir = generatedDir
   // Distinct packages so the generated code does not split-package with
   // polaris-api-catalog-service.
   apiPackage = "org.apache.polaris.service.catalog.semanticmodel.api"
   modelPackage = "org.apache.polaris.service.catalog.semanticmodel.types"
-  ignoreFileOverride.set(provider { rootDir.file(".openapi-generator-ignore").asFile.absolutePath })
+  ignoreFileOverride = rootDir.file(".openapi-generator-ignore")
   removeOperationIdPrefix.set(true)
-  templateDir.set(provider { templatesDir.asFile.absolutePath })
+  templateDir = templatesDir
   globalProperties.put("apis", "SemanticModelApi")
   globalProperties.put("models", semanticModelModels)
   globalProperties.put("apiDocs", "false")
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 0b9515975f..f7134ab7d6 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -128,6 +128,6 @@ weld-core-bom = { module = "org.jboss.weld:weld-core-bom", version = "6.0.4.Fina
 jcstress = { id = "io.github.reyerizo.gradle.jcstress", version = "1.0.0" }
 jetbrains-changelog = { id = "org.jetbrains.changelog",  version = "2.5.0" }
 jmh = { id = "me.champeau.jmh", version = "0.7.3" }
-openapi-generator = { id = "org.openapi.generator", version = "7.12.0" }
+openapi-generator = { id = "org.openapi.generator", version = "7.26.0" }
 quarkus = { id = "io.quarkus", version.ref = "quarkus" }
 rat = { id = "org.nosphere.apache.rat", version = "0.11.0" }
diff --git a/spec/generated/bundled-polaris-catalog-service.yaml b/spec/generated/bundled-polaris-catalog-service.yaml
index eac341e9a9..04a8290475 100644
--- a/spec/generated/bundled-polaris-catalog-service.yaml
+++ b/spec/generated/bundled-polaris-catalog-service.yaml
@@ -17,7 +17,7 @@
 # under the License.
 #
 
-openapi: 3.0.3
+openapi: 3.1.1
 info:
   title: Apache Polaris and Apache Iceberg REST Catalog API
   license:
@@ -2509,8 +2509,9 @@ components:
         Servers that support pagination must return all results in a single response with the value of `next-page-token` set to `null` if the query parameter `pageToken` is not set in the request.
         Servers that do not support pagination should ignore the `pageToken` parameter and return all results in a single response. The `next-page-token` must be omitted from the response.
         Clients must interpret either `null` or missing response value of `next-page-token` as the end of the listing results.
-      type: string
-      nullable: true
+      type:
+        - string
+        - 'null'
     Namespace:
       description: Reference to one or more levels of a namespace
       type: array
@@ -2568,7 +2569,9 @@ components:
         namespace:
           $ref: '#/components/schemas/Namespace'
         properties:
-          type: object
+          type:
+            - object
+            - 'null'
           description: Properties stored on the namespace, if supported by the server. If the server does not support namespace properties, it should return null for this field. If namespace properties are supported, but none are set, it should return an empty object.
           additionalProperties:
             type: string
@@ -2576,7 +2579,6 @@ components:
             owner: Ralph
             transient_lastDdlTime: '1452120468'
           default: {}
-          nullable: true
     UpdateNamespacePropertiesRequest:
       type: object
       properties:
@@ -2612,11 +2614,12 @@ components:
           items:
             type: string
         missing:
-          type: array
+          type:
+            - array
+            - 'null'
           items:
             type: string
           description: List of properties requested for removal that were not found in the namespace's properties. Represents a partial success response. Server's do not need to implement this.
-          nullable: true
     TableIdentifier:
       type: object
       required:
@@ -2627,7 +2630,6 @@ components:
           $ref: '#/components/schemas/Namespace'
         name:
           type: string
-          nullable: false
     ListTablesResponse:
       type: object
       properties:
@@ -3850,9 +3852,10 @@ components:
         - metadata
       properties:
         metadata-location:
-          type: string
+          type:
+            - string
+            - 'null'
           description: May be null if the table is staged as part of a transaction
-          nullable: true
         metadata:
           $ref: '#/components/schemas/TableMetadata'
         config:
@@ -3943,9 +3946,10 @@ components:
         ref:
           type: string
         snapshot-id:
-          type: integer
+          type:
+            - integer
+            - 'null'
           format: int64
-          nullable: true
     AssertLastAssignedFieldId:
       description: The table's last assigned column id must match the requirement's `last-assigned-field-id`
       allOf:
@@ -4985,8 +4989,9 @@ components:
             $ref: '#/components/schemas/StorageAccessConfig'
     PolicyType:
       description: The type of a policy
-      type: string
-      nullable: true
+      type:
+        - string
+        - 'null'
       example: system.data-compaction
     PolicyIdentifier:
       type: object
@@ -4998,7 +5003,6 @@ components:
           $ref: '#/components/schemas/Namespace'
         name:
           type: string
-          nullable: false
     ListPoliciesResponse:
       type: object
       properties:
diff --git a/spec/iceberg-rest-catalog-open-api.yaml b/spec/iceberg-rest-catalog-open-api.yaml
index d4256d6e9f..9393da2c31 100644
--- a/spec/iceberg-rest-catalog-open-api.yaml
+++ b/spec/iceberg-rest-catalog-open-api.yaml
@@ -2410,8 +2410,7 @@ components:
         Clients must interpret either `null` or missing response value of `next-page-token` as
         the end of the listing results.
 
-      type: string
-      nullable: true
+      type: [ string, "null" ]
 
     TableIdentifier:
       type: object
@@ -2423,7 +2422,6 @@ components:
           $ref: '#/components/schemas/Namespace'
         name:
           type: string
-          nullable: false
 
     CatalogObjectIdentifier:
       description:
@@ -3739,9 +3737,8 @@ components:
         ref:
           type: string
         snapshot-id:
-          type: integer
+          type: [ integer, "null" ]
           format: int64
-          nullable: true
 
     AssertLastAssignedFieldId:
       description:
@@ -4270,9 +4267,8 @@ components:
         - metadata
       properties:
         metadata-location:
-          type: string
+          type: [ string, "null"]
           description: May be null if the table is staged as part of a transaction
-          nullable: true
         metadata:
           $ref: '#/components/schemas/TableMetadata'
         config:
@@ -4955,7 +4951,7 @@ components:
         namespace:
           $ref: '#/components/schemas/Namespace'
         properties:
-          type: object
+          type: [ object, "null" ]
           description:
             Properties stored on the namespace, if supported by the server.
             If the server does not support namespace properties, it should return null for this field.
@@ -4964,7 +4960,6 @@ components:
             type: string
           example: { "owner": "Ralph", 'transient_lastDdlTime': '1452120468' }
           default: { }
-          nullable: true
 
     ListTablesResponse:
       type: object
@@ -5293,14 +5288,13 @@ components:
           items:
             type: string
         missing:
-          type: array
+          type: [ array, "null" ]
           items:
             type: string
           description:
             List of properties requested for removal that were not found
             in the namespace's properties. Represents a partial success response.
             Server's do not need to implement this.
-          nullable: true
 
     CommitTableResponse:
       type: object
diff --git a/spec/polaris-catalog-apis/policy-apis.yaml b/spec/polaris-catalog-apis/policy-apis.yaml
index a8c6824924..a90e00f3e7 100644
--- a/spec/polaris-catalog-apis/policy-apis.yaml
+++ b/spec/polaris-catalog-apis/policy-apis.yaml
@@ -482,8 +482,7 @@ components:
 
     PolicyType:
       description: The type of a policy
-      type: string
-      nullable: true
+      type: [string, "null"]
       example: system.data-compaction
 
     PolicyName:
@@ -637,7 +636,6 @@ components:
           $ref: '../iceberg-rest-catalog-open-api.yaml#/components/schemas/Namespace'
         name:
           type: string
-          nullable: false
 
     ListPoliciesResponse:
       type: object
diff --git a/spec/polaris-catalog-service.yaml b/spec/polaris-catalog-service.yaml
index 7166a20ba1..adb41328b3 100644
--- a/spec/polaris-catalog-service.yaml
+++ b/spec/polaris-catalog-service.yaml
@@ -18,7 +18,7 @@
 #
 
 ---
-openapi: 3.0.3
+openapi: 3.1.1
 info:
   title: Apache Polaris and Apache Iceberg REST Catalog API
   license:
diff --git a/spec/polaris-management-service.yml b/spec/polaris-management-service.yml
index 589c827ef4..c85953304d 100644
--- a/spec/polaris-management-service.yml
+++ b/spec/polaris-management-service.yml
@@ -16,7 +16,7 @@
 #  under the License.
 
 
-openapi: 3.0.3
+openapi: 3.1.1
 info:
   title: Polaris Management Service
   version: 0.0.1