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
- 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
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