Summary
azd provision reports a failed post-provision hook (exit code: 1) due to a rm -rf cleanup failure on the temporary Python
virtual environment. All actual Azure resource provisioning and configuration steps complete successfully before this error
occurs.
Root Cause
The script scripts/postProvision.sh uses set -euo pipefail (correct for provisioning logic), but the cleanup block at the end
has no error handling:
deactivate
rm -rf config/.venv_temp
On macOS with Python 3.14, rm -rf fails with "Directory not empty" when .pyc files or file handles are still held open briefly
after python -m invocations. Under set -e, this causes the entire script to exit with failure.
Additionally, deactivate may reference undefined shell variables ($_OLD_VIRTUAL_PS1) under set -u in non-interactive shells.
Steps to Reproduce
1. Run azd init -t azure/gpt-rag on macOS with Python
3.14
2. Run azd provision
3. All Azure resources provision successfully
4. Observe the cleanup failure:
🧹 Cleaning Python environment up…
rm: config/.venv_temp/lib/python3.14: Directory not empty
ERROR: failed running post hooks: 'postprovision' hook failed with exit code: '1'
Expected Behavior
The hook should report success when all provisioning steps complete. Cleanup failures should not be fatal.
Proposed Solution
Register cleanup as a trap EXIT handler so it always runs and never propagates its exit code:
cleanup() {
deactivate 2>/dev/null || true
rm -rf config/.venv_temp 2>/dev/null || true
}
trap cleanup EXIT
Note: The equivalent postProvision.ps1 already has its cleanup commented out with retry logic, confirming this class of failure
was already identified on Windows.
Affected Files
- scripts/postProvision.sh — cleanup block at the end of the file
Summary
azd provisionreports a failed post-provision hook (exit code: 1) due to arm -rfcleanup failure on the temporary Pythonvirtual environment. All actual Azure resource provisioning and configuration steps complete successfully before this error
occurs.
Root Cause
The script
scripts/postProvision.shusesset -euo pipefail(correct for provisioning logic), but the cleanup block at the endhas no error handling: