az resource wait --custom returns exit code 0 when condition times out
- Dominant language
- Python
- Stars
- 4.6k
- Forks
- 3.5k
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 60
Description
### Describe the bug
`az resource wait --custom` honors `--timeout`, but when the custom condition remains false for the entire timeout, the command prints `{}` and exits with code `0`.
A true condition also exits with code `0`, so scripts and CI systems cannot distinguish condition satisfaction from timeout.
The current `dev` source still contains the apparent root cause in `src/azure-cli-core/azure/cli/core/commands/command_operation.py`: `WaitCommandOperation.wait` returns a `CLIError` object on timeout instead of raising it.
```python
progress_indicator.end()
return CLIError('Wait operation timed-out after {} seconds'.format(timeout))
```
This appears to affect generic Azure CLI wait commands, not only this resource type.
### Related command
```bash
az resource wait --ids "" --custom "properties.connectivityStatus=='Connecting'" --interval 5 --timeout 30
```
### Errors
No error is emitted. The timeout result is:
```text
{}
exit code: 0
elapsed time: 33 seconds
```
### Issue script and debug output
Given an existing ARM resource whose `properties.connectivityStatus` is `Connected`:
```bash
az resource show \
--ids "" \
--query "{connectivityStatus:properties.connectivityStatus,provisioningState:properties.provisioningState}" \
-o json
```
Result:
```json
{
"connectivityStatus": "Connected",
"provisioningState": "Succeeded"
}
```
Positive control - true condition:
```bash
az resource wait \
--ids "" \
--custom "properties.connectivityStatus=='Connected'" \
--interval 15 \
--timeout 900
echo $?
```
Observed:
```text
exit code: 0
elapsed time: 1.6 seconds
```
Negative test - false condition:
```bash
start_time=$(date +%s)
az resource wait \
--ids "" \
--custom "properties.connectivityStatus=='Connecting'" \
--interval 5 \
--timeout 30
wait_exit_code=$?
elapsed_seconds=$(($(date +%s) - start_time))
printf 'wait_exit_code=%s\nelapsed_seconds=%s\n' \
"$wait_exit_code" \
"$elapsed_seconds"
```
Observed:
```text
{}
wait_exit_code=0
elapsed_seconds=33
```
Impossible-condition test:
```bash
start_time=$(date +%s)
output=$(az resource wait \
--ids "" \
--custom "properties.connectivityStatus=='DefinitelyNotAStatus'" \
--interval 2 \
--timeout 10 2>&1)
wait_exit_code=$?
elapsed_seconds=$(($(date +%s) - start_time))
printf 'output=%s\nwait_exit_code=%s\nelapsed_seconds=%s\n' \
"$output" \
"$wait_exit_code" \
"$elapsed_seconds"
```
Observed:
```text
output={}
wait_exit_code=0
elapsed_seconds=12
```
The impossible value rules out a transient state transition. No resource identifiers or debug output are included because they are unnecessary for reproduction.
### Expected behavior
When `--timeout` expires before `--custom` evaluates to true, the command should:
1. Exit with a nonzero code.
2. Emit `Wait operation timed-out after seconds` or another clear timeout error.
3. Remain distinguishable from successful condition satisfaction in automation.
### Environment Summary
```text
Azure CLI: 2.89.1
azure-cli-core: 2.89.1
azure-cli-telemetry: 1.1.0
OS: Linux 6.17.0-1022-azure, x86_64
Shell: GNU bash 5.2.21
Resource type: Microsoft.Kubernetes/connectedClusters
```
The same timeout code path remains present on current `dev` commit `b92a89e7781c11a5ee8437a84ef4b8fd9edab4f0` (August 27, 2026).
### Additional context
Related but not duplicate:
- #28523 reports another command returning exit code `0` on failure.
- #32961 reports a custom JMESPath condition returning immediately, rather than timeout being returned as success.
Contributor guide
Assessment
This issue has not been assessed yet.