Cannot update existing APIM api with import command: `(ValidationError) API with specified version 'v1' already exists`
Describe the bug
I imported an api into a versionset with import command:
az apim api import --subscription <sub-id> -g <rg-name> --service-name <apim-name> -o table --path '/spec' --specification-format "OpenApiJson" --specification-path spec.json --api-version-set-id echo-v1 --api-version v1
I wanted to update it so that the endpoints are updated in the portal within the same version (ideally as a new revision), so I used the same command.
However, the cli returns an error specified below.
If add manually a revision id ( --api-revision 2) the import succeeds, but it is added into a new entry to the versionset instead of adding a revision to existing version:
Am I under a wrong impression that this is supposed to work this way? Is there any other command I should use to update existing api/version using openapi schema?
Related command
az apim api import
Errors
cli.azure.cli.core.azclierror: (ValidationError) API with specified version 'v1' already exists
Code: ValidationError
Message: API with specified version 'v1' already exists
az_command_data_logger: (ValidationError) API with specified version 'v1' already exists
Code: ValidationError
Message: API with specified version 'v1' already exists
Issue script & Debug output
Show debug output
cli.knack.cli: Command arguments: ['apim', 'api', 'import', '--subscription', '<sub-id>', '-g', '<rg-name>', '--service-name', '<apim-name>', '-o', 'table', '--path', '/spec', '--specification-format', 'OpenApiJson', '--specification-path', '.\\Downloads\\spec.json', '--api-version-set-id', 'echo-v1', '--api-version', 'v1', '--debug']
cli.knack.cli: __init__ debug log:
Enable color in terminal.
cli.knack.cli: Event: Cli.PreExecute []
cli.knack.cli: Event: CommandParser.OnGlobalArgumentsCreate [<function CLILogging.on_global_arguments at 0x000001703FA6B880>, <function OutputProducer.on_global_arguments at 0x000001703FBF6020>, <function CLIQuery.on_global_arguments at 0x000001703FC23BA0>]
cli.knack.cli: Event: CommandInvoker.OnPreCommandTableCreate []
cli.azure.cli.core: Modules found from index for 'apim': ['azure.cli.command_modules.apim']
cli.azure.cli.core: Loading command modules:
cli.azure.cli.core: Name Load Time Groups Commands
cli.azure.cli.core: apim 0.008 14 69
cli.azure.cli.core: Total (1) 0.008 14 69
cli.azure.cli.core: Loaded 14 groups, 69 commands.
cli.azure.cli.core: Found a match in the command table.
cli.azure.cli.core: Raw command : apim api import
cli.azure.cli.core: Command table: apim api import
cli.knack.cli: Event: CommandInvoker.OnPreCommandTableTruncate [<function AzCliLogging.init_command_file_logging at 0x0000017042B4EE80>]
cli.azure.cli.core.azlogging: metadata file logging enabled - writing logs to 'C:\Users\<user_dir>\.azure\commands\2024-05-07.12-16-54.apim_api_import.15920.log'.
az_command_data_logger: command args: apim api import --subscription {} -g {} --service-name {} -o {} --path {} --specification-format {} --specification-path {} --api-version-set-id {} --api-version {} --debug
cli.knack.cli: Event: CommandInvoker.OnPreArgumentLoad [<function register_global_subscription_argument.<locals>.add_subscription_parameter at 0x0000017042B5B4C0>]
cli.knack.cli: Event: CommandInvoker.OnPostArgumentLoad []
cli.knack.cli: Event: CommandInvoker.OnPostCommandTableCreate [<function register_ids_argument.<locals>.add_ids_arguments at 0x0000017042B9D3A0>, <function register_cache_arguments.<locals>.add_cache_arguments at 0x0000017042B9D4E0>]
cli.knack.cli: Event: CommandInvoker.OnCommandTableLoaded []
cli.knack.cli: Event: CommandInvoker.OnPreParseArgs []
cli.knack.cli: Event: CommandInvoker.OnPostParseArgs [<function OutputProducer.handle_output_argument at 0x000001703FBF60C0>, <function CLIQuery.handle_query_parameter at 0x000001703FC23C40>, <function register_ids_argument.<locals>.parse_ids_arguments at 0x0000017042B9D440>]
cli.azure.cli.core.commands.client_factory: Getting management service client client_type=ApiManagementClient
cli.azure.cli.core.auth.persistence: build_persistence: location='C:\\Users\\<user_dir>\\.azure\\msal_token_cache.bin', encrypt=True
cli.azure.cli.core.auth.binary_cache: load: C:\Users\<user_dir>\.azure\msal_http_cache.bin
urllib3.util.retry: Converted retries value: 1 -> Retry(total=1, connect=None, read=None, redirect=None, status=None)
msal.authority: openid_config = {'token_endpoint': 'https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token', 'token_endpoint_auth_methods_supported': ['client_secret_post', 'private_key_jwt', 'client_secret_basic'], 'jwks_uri': 'https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys', 'response_modes_supported': ['query', 'fragment', 'form_post'], 'subject_types_supported': ['pairwise'], 'id_token_signing_alg_values_supported': ['RS256'], 'response_types_supported': ['code', 'id_token', 'code id_token', 'id_token token'], 'scopes_supported': ['openid', 'profile', 'email', 'offline_access'], 'issuer': 'https://login.microsoftonline.com/<tenant-id>/v2.0', 'request_uri_parameter_supported': False, 'userinfo_endpoint': 'https://graph.microsoft.com/oidc/userinfo', 'authorization_endpoint': 'https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize', 'device_authorization_endpoint': 'https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/devicecode', 'http_logout_supported': True, 'frontchannel_logout_supported': True, 'end_session_endpoint': 'https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/logout', 'claims_supported': ['sub', 'iss', 'cloud_instance_name', 'cloud_instance_host_name', 'cloud_graph_host_name', 'msgraph_host', 'aud', 'exp', 'iat', 'auth_time', 'acr', 'nonce', 'preferred_username', 'name', 'tid', 'ver', 'at_hash', 'c_hash', 'email'], 'kerberos_endpoint': 'https://login.microsoftonline.com/<tenant-id>/kerberos', 'tenant_region_scope': 'EU', 'cloud_instance_name': 'microsoftonline.com', 'cloud_graph_host_name': 'graph.windows.net', 'msgraph_host': 'graph.microsoft.com', 'rbac_url': 'https://pas.windows.net'}
msal.application: Broker enabled? None
cli.azure.cli.core.auth.credential_adaptor: CredentialAdaptor.get_token: scopes=('https://management.core.windows.net//.default',), kwargs={}
cli.azure.cli.core.auth.msal_authentication: UserCredential.get_token: scopes=('https://management.core.windows.net//.default',), claims=None, kwargs={}
msal.application: Cache hit an AT
msal.telemetry: Generate or reuse correlation_id: b6ea7651-7728-4f2c-8285-409de63ad64d
cli.azure.cli.core.sdk.policies: Request URL: 'https://management.azure.com/subscriptions/<sub-id>/resourceGroups/<rg-name>/providers/Microsoft.ApiManagement/service/<apim-name>/apis/f52ab8e46aea4e6dbd1c25f5af36a381?api-version=2022-08-01'
cli.azure.cli.core.sdk.policies: Request method: 'PUT'
cli.azure.cli.core.sdk.policies: Request headers:
cli.azure.cli.core.sdk.policies: 'Content-Type': 'application/json'
cli.azure.cli.core.sdk.policies: 'Content-Length': '68824'
cli.azure.cli.core.sdk.policies: 'Accept': 'application/json'
cli.azure.cli.core.sdk.policies: 'x-ms-client-request-id': 'edb33bac-0c5a-11ef-9e5f-a002a54c8717'
cli.azure.cli.core.sdk.policies: 'CommandName': 'apim api import'
cli.azure.cli.core.sdk.policies: 'ParameterSetName': '--subscription -g --service-name -o --path --specification-format --specification-path --api-version-set-id --api-version --debug'
cli.azure.cli.core.sdk.policies: 'User-Agent': 'AZURECLI/2.59.0 (MSI) azsdk-python-core/1.28.0 Python/3.11.8 (Windows-10-10.0.22631-SP0)'
cli.azure.cli.core.sdk.policies: 'Authorization': '*****'
cli.azure.cli.core.sdk.policies: Request body:
cli.azure.cli.core.sdk.policies: <content of the openapi schema>
urllib3.connectionpool: Starting new HTTPS connection (1): management.azure.com:443
urllib3.connectionpool: https://management.azure.com:443 "PUT /subscriptions/<sub-id>/resourceGroups/<rg-name>/providers/Microsoft.ApiManagement/service/<apim-name>/apis/f52ab8e46aea4e6dbd1c25f5af36a381?api-version=2022-08-01 HTTP/1.1" 202 0
cli.azure.cli.core.sdk.policies: Response status: 202
cli.azure.cli.core.sdk.policies: Response headers:
cli.azure.cli.core.sdk.policies: 'Cache-Control': 'no-cache'
cli.azure.cli.core.sdk.policies: 'Pragma': 'no-cache'
cli.azure.cli.core.sdk.policies: 'Expires': '-1'
cli.azure.cli.core.sdk.policies: 'Location': 'https://management.azure.com/subscriptions/<sub-id>/resourceGroups/<rg-name>/providers/Microsoft.ApiManagement/service/<apim-name>/apis/f52ab8e46aea4e6dbd1c25f5af36a381?api-version=2022-08-01&asyncId=6639ff9746346104641f9da9&asyncCode=201'
cli.azure.cli.core.sdk.policies: 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains'
cli.azure.cli.core.sdk.policies: 'X-Content-Type-Options': 'nosniff'
cli.azure.cli.core.sdk.policies: 'x-ms-request-id': 'e51b0f55-a130-4051-9481-3ce2e15d9fa0'
cli.azure.cli.core.sdk.policies: 'x-ms-ratelimit-remaining-subscription-writes': '1199'
cli.azure.cli.core.sdk.policies: 'x-ms-correlation-request-id': 'e51b0f55-a130-4051-9481-3ce2e15d9fa0'
cli.azure.cli.core.sdk.policies: 'x-ms-routing-request-id': 'GERMANYWESTCENTRAL:20240507T101655Z:e51b0f55-a130-4051-9481-3ce2e15d9fa0'
cli.azure.cli.core.sdk.policies: 'X-Cache': 'CONFIG_NOCACHE'
cli.azure.cli.core.sdk.policies: 'X-MSEdge-Ref': 'Ref A: 52B5618F68424B94BFBE52D67046B6CF Ref B: VIEEDGE1618 Ref C: 2024-05-07T10:16:54Z'
cli.azure.cli.core.sdk.policies: 'Date': 'Tue, 07 May 2024 10:16:54 GMT'
cli.azure.cli.core.sdk.policies: 'Content-Length': '0'
cli.azure.cli.core.sdk.policies: Response content:
cli.azure.cli.core.sdk.policies:
cli.azure.cli.core.sdk.policies: Request URL: 'https://management.azure.com/subscriptions/<sub-id>/resourceGroups/<rg-name>/providers/Microsoft.ApiManagement/service/<apim-name>/apis/f52ab8e46aea4e6dbd1c25f5af36a381?api-version=2022-08-01&asyncId=6639ff9746346104641f9da9&asyncCode=201'
cli.azure.cli.core.sdk.policies: Request method: 'GET'
cli.azure.cli.core.sdk.policies: Request headers:
cli.azure.cli.core.sdk.policies: 'x-ms-client-request-id': 'edb33bac-0c5a-11ef-9e5f-a002a54c8717'
cli.azure.cli.core.sdk.policies: 'CommandName': 'apim api import'
cli.azure.cli.core.sdk.policies: 'ParameterSetName': '--subscription -g --service-name -o --path --specification-format --specification-path --api-version-set-id --api-version --debug'
cli.azure.cli.core.sdk.policies: 'User-Agent': 'AZURECLI/2.59.0 (MSI) azsdk-python-core/1.28.0 Python/3.11.8 (Windows-10-10.0.22631-SP0)'
cli.azure.cli.core.sdk.policies: 'Authorization': '*****'
cli.azure.cli.core.sdk.policies: Request body:
cli.azure.cli.core.sdk.policies: This request has no body
urllib3.connectionpool: https://management.azure.com:443 "GET /subscriptions/<sub-id>/resourceGroups/<rg-name>/providers/Microsoft.ApiManagement/service/<apim-name>/apis/f52ab8e46aea4e6dbd1c25f5af36a381?api-version=2022-08-01&asyncId=6639ff9746346104641f9da9&asyncCode=201 HTTP/1.1" 400 110
cli.azure.cli.core.sdk.policies: Response status: 400
cli.azure.cli.core.sdk.policies: Response headers:
cli.azure.cli.core.sdk.policies: 'Cache-Control': 'no-cache'
cli.azure.cli.core.sdk.policies: 'Pragma': 'no-cache'
cli.azure.cli.core.sdk.policies: 'Content-Length': '110'
cli.azure.cli.core.sdk.policies: 'Content-Type': 'application/json; charset=utf-8'
cli.azure.cli.core.sdk.policies: 'Expires': '-1'
cli.azure.cli.core.sdk.policies: 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains'
cli.azure.cli.core.sdk.policies: 'X-Content-Type-Options': 'nosniff'
cli.azure.cli.core.sdk.policies: 'x-ms-request-id': '25b70b20-347c-4a65-b271-184e0620584d'
cli.azure.cli.core.sdk.policies: 'x-ms-ratelimit-remaining-subscription-reads': '11998'
cli.azure.cli.core.sdk.policies: 'x-ms-correlation-request-id': '25b70b20-347c-4a65-b271-184e0620584d'
cli.azure.cli.core.sdk.policies: 'x-ms-routing-request-id': 'GERMANYWESTCENTRAL:20240507T101655Z:25b70b20-347c-4a65-b271-184e0620584d'
cli.azure.cli.core.sdk.policies: 'X-Cache': 'CONFIG_NOCACHE'
cli.azure.cli.core.sdk.policies: 'X-MSEdge-Ref': 'Ref A: 56C2B27E493C4052BBE432B46C337196 Ref B: VIEEDGE1618 Ref C: 2024-05-07T10:16:55Z'
cli.azure.cli.core.sdk.policies: 'Date': 'Tue, 07 May 2024 10:16:55 GMT'
cli.azure.cli.core.sdk.policies: Response content:
cli.azure.cli.core.sdk.policies: {"error":{"code":"ValidationError","message":"API with specified version 'v1' already exists","details":null}}
cli.azure.cli.core.azclierror: Traceback (most recent call last):
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/base_polling.py", line 730, in run
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/base_polling.py", line 756, in _poll
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/base_polling.py", line 782, in update_status
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/base_polling.py", line 156, in _raise_if_bad_http_status_and_method
azure.core.polling.base_polling.BadStatus: Invalid return status 400 for 'GET' operation
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\knack/cli.py", line 233, in invoke
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 664, in execute
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 731, in _run_jobs_serially
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 712, in _run_job
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 1048, in __call__
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 1035, in __call__
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/_poller.py", line 242, in result
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/tracing/decorator.py", line 76, in wrapper_use_tracer
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/_poller.py", line 261, in wait
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/_poller.py", line 176, in _start
File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/polling/base_polling.py", line 734, in run
azure.core.exceptions.HttpResponseError: (ValidationError) API with specified version 'v1' already exists
Code: ValidationError
Message: API with specified version 'v1' already exists
cli.azure.cli.core.azclierror: (ValidationError) API with specified version 'v1' already exists
Code: ValidationError
Message: API with specified version 'v1' already exists
az_command_data_logger: (ValidationError) API with specified version 'v1' already exists
Code: ValidationError
Message: API with specified version 'v1' already exists
cli.knack.cli: Event: Cli.PostExecute [<function AzCliLogging.deinit_cmd_metadata_logging at 0x0000017042B4F100>]
az_command_data_logger: exit code: 1
cli.__main__: Command ran in 2.601 seconds (init: 0.213, invoke: 2.389)
telemetry.main: Begin splitting cli events and extra events, total events: 1
telemetry.client: Accumulated 0 events. Flush the clients.
telemetry.main: Finish splitting cli events and extra events, cli events: 1
telemetry.save: Save telemetry record of length 3962 in cache
telemetry.main: Begin creating telemetry upload process.
telemetry.process: Creating upload process: "C:\Program Files\Microsoft SDKs\Azure\CLI2\python.exe C:\Program Files\Microsoft SDKs\Azure\CLI2\Lib\site-packages\azure\cli\telemetry\__init__.pyc C:\Users\<user_dir>\.azure"
telemetry.process: Return from creating process
telemetry.main: Finish creating telemetry upload process.
Expected behavior
I was expecting, that the new revision will be created for existing version v1 and it would contain new schema.
Environment Summary
azure-cli 2.59.0 *
core 2.59.0 *
telemetry 1.1.0
Dependencies:
msal 1.27.0
azure-mgmt-resource 23.1.0b2
Python location 'C:\Program Files\Microsoft SDKs\Azure\CLI2\python.exe'
Extensions directory 'C:\Users\<user_dir>\.azure\cliextensions'
Python (Windows) 3.11.8 (tags/v3.11.8:db85d51, Feb 6 2024, 22:03:32) [MSC v.1937 64 bit (AMD64)]
Legal docs and information: aka.ms/AzureCliLegal
Additional context
No response
Hi @rgembalik,
2.59.0 is not the latest Azure CLI(2.60.0).
If you haven't already attempted to do so, please upgrade to the latest Azure CLI version by following https://learn.microsoft.com/en-us/cli/azure/update-azure-cli.
Thank you for opening this issue, we will look into it.
Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @solankisamir, @mikebudzynski, @KedarJoshi, @yingru97.
A small update: the same happens on version 2.60.0
I realized today that when I use az apim api import together with --api-revision, all revisions are overwritten with the referenced api spec. Might this be related?
@rgembalik I ran into the same issue for a versioned API, setup with a named versionset. Not sure if it is a workaround or as intended, but I seem to be able to get it up and running by providing the --api-id parameter constructed out of the parts
- The (internal) name (=underlying resource name) of the API, in your example
test-echo - The target version like
v1
So --api-id test-echo-v1, which is also reported as .name property of that versioned API if you would execute a az apim api list --resource-group rg-something --service-name apim-something
Then the --path parameter, which also is a required parameter. That needs to be provided unversioned, so test-echo in your example. Which is also matching the reported .path property of above mentioned API listing. ... Or at least in my setup it does match.
p.s. What is not clear to me based on the documentation of command here: is that the --api-version-set-id needs to be provided as name of the version set, and not the full resourceId (with subscription, resourcegroup, namespace etc) as is needed in the BICEP/ARM templates with which we setup the API initially.
Hope it helps!