Azure / Azure/azure-devops-cli-extension

[BUG] `az devops invoke` fails with "could not convert string to float: '7.1.1'" when a resource advertises a 3-part max_version

Open
#1,519 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
682
Forks
278
Avg merge
3d 23h
Merged PRs (30d)
3

Description

## Summary

`az devops invoke` raises `ERROR: could not convert string to float: '7.1.1'` when the target Azure DevOps server advertises a **three-part** `max_version` (e.g. `7.1.1`) for the requested resource. The failure happens during resource-location matching, **before** the request is sent, so it fires regardless of the `--api-version` value the caller passes.

## Repro

Against an Azure DevOps organization whose `wit/tags` resource advertises `max_version = 7.1.1`:

```
$ az devops invoke --org https://dev.azure.com/ \
--area wit --resource tags --http-method GET \
--api-version 7.1-preview.1 --detect false \
--route-parameters project= --output json
ERROR: could not convert string to float: '7.1.1'
```

The same error occurs with any `--api-version`, and with no `--api-version` at all.

## Root cause

`azext_devops/dev/team/invoke.py` casts the server-provided resource-location version to `float`:

```python
# invoke.py, in the resource-location loop
current_maxVersion = float(resource_location.max_version)
```

`float('7.1.1')` raises `ValueError`. `max_version` is a version string, not a number — a two-segment `7.1` happens to parse as a float, but a three-segment `7.1.1` does not. The sibling helper `apiVersionToFloat()` and the SDK's `devops_sdk/client.py` (`float(requested_api_version)`, `float(location.released_version)`) share the same assumption that API versions are two-segment floats.

This is the same class of bug as #946 (preview versions treated as floats): version strings must be compared as versions, not cast to `float`.

## Affected versions

Reproduced on azure-devops extension **1.0.2** and **1.0.8** (latest on the extension index as of 2026-09-11), azure-cli 2.87.0, Python 3.12. Line 90 is unchanged between the two versions.

## Expected

`az devops invoke` should compare `max_version` / `min_version` / `released_version` as version tuples (or use `packaging.version.Version` / a `LooseVersion`-style parse), so a resource advertising `7.1.1` is handled the same as one advertising `7.1`.

## Workaround

`az rest` against the resource's REST URL directly is unaffected, because it does not run the resource-location negotiation:

```
az rest --method GET \
--uri "https://dev.azure.com///_apis/wit/tags?api-version=7.1-preview.1" ...
```

## Additional context

Filed from an automated tooling context that reads Azure DevOps work-item tags via `az devops invoke`; the three-part `max_version` began appearing on our server and broke every `invoke` read. Happy to test a fix build.

Contributor guide

Open the contributing guide

Research direction

Start in azext_devops/dev/team/invoke.py at the resource-location loop and review apiVersionToFloat(), then inspect devops_sdk/client.py for the related version conversions. Reproduce the three-part max_version case and verify that resource-location negotiation handles max_version, min_version, and released_version without float-conversion errors, including the existing --api-version variations.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, python
Domain
api, cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.