Skip to content

fix(appconfiguration): handle 403 Forbidden to avoid JSONDecodeError#46446

Open
ChristineWanjau wants to merge 3 commits intoAzure:mainfrom
ChristineWanjau:cwanjau/fixCrashNoDataPlaneRoles
Open

fix(appconfiguration): handle 403 Forbidden to avoid JSONDecodeError#46446
ChristineWanjau wants to merge 3 commits intoAzure:mainfrom
ChristineWanjau:cwanjau/fixCrashNoDataPlaneRoles

Conversation

@ChristineWanjau
Copy link
Copy Markdown

@ChristineWanjau ChristineWanjau commented Apr 21, 2026

Description

When a caller lacks data plane reader role, dataplane requests in the cli crash with this error, for example,
az appconfig kv list --endpoint https://test.azconfig.io --auth-mode login

The command failed with an unexpected error. Here is the traceback:
Expecting value: line 1 column 1 (char 0)
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 682, in execute
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 812, 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 781, in _run_job
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 336, in __call__
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/command_operation.py", line 120, in handler
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/command_modules/appconfig/keyvalue.py", line 834, in list_key
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/command_modules/appconfig/_kv_helpers.py", line 113, in __read_kv_from_config_store
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/paging.py", line 136, in __next__
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/paging.py", line 82, in __next__
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/appconfiguration/_models.py", line 601, in _get_next_cb
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/tracing/decorator.py", line 119, in wrapper_use_tracer
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/appconfiguration/_generated/_operations/_patch.py", line 169, in get_key_values_in_one_page
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/core/rest/_http_response_impl.py", line 331, in json
  File "json\__init__.py", line 352, in loads
  File "json\decoder.py", line 345, in decode
  File "json\decoder.py", line 363, in raw_decode
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Because 403 was not present in error_map, map_error() returned silently and the code proceeded to call response.json() on the empty body, crashing with a JSONDecodeError.

Changes
_generated/_operations/_patch.py

Added 403: HttpResponseError to error_map so map_error() raises immediately on Forbidden responses, before any deserialization is attempted.
Wrapped response.json() in try/except as a defensive guard for any other unmapped status codes that may also return empty or malformed bodies.

All SDK Contribution checklist:

  • The pull request does not introduce [breaking changes]
  • CHANGELOG is updated for new features, bug fixes or other significant changes.
  • I have read the contribution guidelines.

General Guidelines and Best Practices

  • Title of the pull request is clear and informative.
  • There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, see this page.

Testing Guidelines

  • Pull request includes test coverage for the included changes.

Copilot AI review requested due to automatic review settings April 21, 2026 16:27
@github-actions github-actions Bot added the App Configuration Azure.ApplicationModel.Configuration label Apr 21, 2026
@ChristineWanjau ChristineWanjau changed the title fix: fix(appconfiguration): handle 403 Forbidden with empty body to avoid JSONDecodeError Apr 21, 2026
@ChristineWanjau ChristineWanjau changed the title fix(appconfiguration): handle 403 Forbidden with empty body to avoid JSONDecodeError fix(appconfiguration): handle 403 Forbidden to avoid JSONDecodeError Apr 21, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a crash in the Azure App Configuration Python SDK when a data-plane request returns HTTP 403 with an empty response body (previously leading to JSONDecodeError during error deserialization), improving CLI and SDK robustness for insufficient-role scenarios.

Changes:

  • Added HTTP 403 to the generated operation error_map so map_error() raises immediately for Forbidden responses.
  • Wrapped error-body deserialization in a try/except to avoid crashing when the error response body is empty/malformed.
  • Documented the fix in the package CHANGELOG.md under 1.8.1 (Unreleased).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
sdk/appconfiguration/azure-appconfiguration/azure/appconfiguration/_generated/_operations/_patch.py Updates paging operation error handling to raise on 403 and defensively handle non-JSON/empty error bodies.
sdk/appconfiguration/azure-appconfiguration/CHANGELOG.md Adds a release note describing the 403/empty-body crash fix and the defensive deserialization guard.

Comment on lines +199 to +202
try:
error = _deserialize(_models.Error, response.json())
except (ValueError, KeyError):
raise HttpResponseError(response=response)
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The defensive guard currently only catches (ValueError, KeyError), but _deserialize(...) can raise azure.core.exceptions.DeserializationError (see azure/appconfiguration/_generated/_model_base.py). If the service returns non-empty JSON that doesn’t match _models.Error, this would still surface as an unexpected exception type. Consider catching DeserializationError here as well, and raising HttpResponseError instead (ideally raise ... from exc to preserve the original error context).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Comment on lines +200 to +202
error = _deserialize(_models.Error, response.json())
except (ValueError, KeyError):
raise HttpResponseError(response=response)
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is addressing a user-facing crash path (403 + empty body) and adds new branching in the error handling for paging. Please add a unit test that simulates a 403 response with an empty body and asserts the client raises HttpResponseError (and does not raise JSONDecodeError). The existing unit tests in tests/test_azure_appconfiguration_client*.py already use custom MockTransport patterns that could be extended for this scenario.

Suggested change
error = _deserialize(_models.Error, response.json())
except (ValueError, KeyError):
raise HttpResponseError(response=response)
error_payload = response.json()
except (ValueError, KeyError, TypeError):
raise HttpResponseError(response=response)
if not error_payload:
raise HttpResponseError(response=response)
try:
error = _deserialize(_models.Error, error_payload)
except (ValueError, KeyError, TypeError):
raise HttpResponseError(response=response)

Copilot uses AI. Check for mistakes.
Comment thread sdk/appconfiguration/azure-appconfiguration/CHANGELOG.md Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

App Configuration Azure.ApplicationModel.Configuration

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants