Skip to content

network-watcher packet-capture create: unescaped C:\Captures\... in docstring emits SyntaxWarning on first run and corrupts the help example #34136

Description

@beenet-bytes

Describe the bug

src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/network_watcher/packet_capture/_create.py, line 21, has a Windows path inside the class docstring, which is a normal (non-raw) string:

"filePath": "C:\Captures\testByCli.cap"

That has two effects:

  1. \C is an invalid escape sequence. Python has warned on invalid escapes by default since 3.12; on the 3.14.7 build tested here, the first import of the module (before its .pyc is cached) prints a SyntaxWarning to stderr.
  2. \t is a valid escape, so it's consumed too: the example in --help ends up with blank space where \t was written, not the literal characters: "C:\Captures estByCli.cap".

The line is unchanged on dev. The file's last commit is #31624 (2025-06-18), well after aaz-dev-tools started escaping backslashes in generated docstrings (Azure/aaz-dev-tools#360, merged 2024-05-20). I don't know whether #31624 regenerated this file or just touched something else in it, so I can't say whether the fix belongs here, in the example source in Azure/aaz, or both.

This isn't the azure-batch SDK warning tracked in #31789 / #32495. That one is in a different package; this file is owned by azure-cli.

Related command

az network network-watcher packet-capture create

Errors

First run after install (no __pycache__ yet for that package):

$ az network network-watcher packet-capture create --help > /dev/null
/opt/homebrew/Cellar/azure-cli/2.90.0/libexec/lib/python3.14/site-packages/azure/cli/command_modules/network/aaz/latest/network/network_watcher/packet_capture/_create.py:21: SyntaxWarning: "\C" is an invalid escape sequence. Such sequences will not work in the future. Did you mean "\\C"? A raw string is also an option.

The second run prints nothing, because the .pyc is cached by then.

Help output (every run):

        "/subscriptions//resourceGroups//providers/Microsoft.Storage/storageAccounts/", "filePath":
        "C:\Captures estByCli.cap"}' --target "/subscriptions/*****/resourceGroups//providers/Micros

Issue script & Debug output

This reproduces without relying on cache state, by compiling the file in memory with az's own interpreter:

PY=/opt/homebrew/Cellar/azure-cli/2.90.0/libexec/bin/python   # az's bundled Python
F=$($PY -c "import azure.cli.command_modules.network as m, os; print(os.path.dirname(m.__file__))")/aaz/latest/network/network_watcher/packet_capture/_create.py
$PY -c "import sys; p=sys.argv[1]; compile(open(p).read(), p, 'exec')" "$F"

Output: the same SyntaxWarning as above.

And where the \t escape ends up:

$PY -W ignore -c "from azure.cli.command_modules.network.aaz.latest.network.network_watcher.packet_capture._create import Create as C; d=C.__doc__; i=d.find('Captures'); print(repr(d[i-5:i+25]))"
# ' "C:\\Captures estByCli.cap"}\' '   <- literal space, not "\t": confirmed chr(9) not in the string

Expected behavior

No warning on stderr, and the help example shows C:\Captures\testByCli.cap. Escaping the backslashes (C:\\Captures\\testByCli.cap) fixes both.

Environment Summary

azure-cli 2.90.0 (latest release), azure-cli-core 2.90.0
Python 3.14.7 (Homebrew bundle)
macOS 26.6.2, arm64, installed via Homebrew

Additional context

The warning only fires on the very first import, before the .pyc is cached (confirmed above). That's an easy trap for anything that merges stderr into parsed output (2>&1): it fails once, then passes silently on retry. A SyntaxWarning shouldn't be on stderr to begin with.

Activity

  1. added
    bugThis issue requires a change to an existing behavior in the product in order to be resolved.
    on Sep 25, 2026
  2. yonzhan commented on Sep 25, 2026

    @yonzhan
    Collaborator

    Thank you for opening this issue, we will look into it.

  3. x-engineering-agent commented on Sep 25, 2026

    @x-engineering-agent
    Contributor

    Bug analysis

    Hi beenet-bytes, the report contains enough evidence to proceed: an exact failing command, actual stderr/help output, expected behavior, and a reproducible version/context. No additional requirements are needed.

    Command, reproduction, and impact

    • Affected command: az network network-watcher packet-capture create; the non-resource reproduction is az network network-watcher packet-capture create --help.
    • Reported environment: Azure CLI/core 2.90.0, bundled Python 3.14.7, Homebrew on macOS 26.6.2 arm64. These version details are reporter-provided, not independently runtime-verified here.
    • The report distinguishes a first-compilation invalid-escape SyntaxWarning from help-example corruption on every run. A cached .pyc can hide the warning on retry, so cold/warm help alone is not a sufficient regression check. The supplied cache-independent reproduction makes this a well-specified report.
    • Expected result: no invalid-escape warning and a help example that preserves the Windows path separators and the full testByCli.cap filename. This is a client-side help/compilation defect; the report does not demonstrate a packet-capture service failure. Stderr-combining callers can be affected on the first invocation.

    Source-confirmed root cause and scope

    Read-only inspection of current dev confirms that network/.../packet_capture/_create.py registers this exact command and uses a normal triple-quoted Create docstring. Its line 21 contains "filePath": "C:\Captures\testByCli.cap" with single source backslashes. Python treats \C as an invalid escape and interprets \t rather than preserving those two literal characters. This is sufficient to explain both the warning and loss of the intended path in the example; it is not an SDK-owned azure-batch warning.

    The file is explicitly generated by aaz-dev-tools. _aaz_info identifies API version 2024-05-01 and resource /subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/packetcaptures/{}. The inspected source blob is cd2a654258b47ee58c991353f413162c7245ba35.

    _parse_cls_doc takes command help/examples from cls.__doc__, after Python has already interpreted its escapes. Exact later whitespace rendering was not independently executed. No tests, issue-provided scripts, Azure resource operations, or implementation changes were run during this triage.

    The durable AAZ example and the reporter's upstream generator/history claims have not been independently verified. The confirmed defect is in the checked-in generated Python; this is not evidence by itself that the current generator or REST specification is defective.

    Suggested fix for the implementation job

    1. Inspect the corresponding durable Azure/aaz command model/example and the current aaz-dev-tools rendering of that example using the command and _aaz_info above. Correct the durable example only if its encoding is wrong; do not double-escape an already-correct model or change the REST API specification without evidence.
    2. Regenerate the existing network module with the supported generator so normal Python docstrings correctly escape literal backslashes. Preserve the intended Windows path and separately validate the JSON/shorthand serialization of --storage-location; Python-literal escaping and CLI argument encoding are different layers. If the current generator still emits invalid Python escapes, isolate and fix the responsible rendering path rather than hand-patching generated output.
    3. Do not directly edit aaz/latest/.../_create.py, suppress warnings, or broadly alter help parsing. Follow the mandatory source/codegen workflow below, review the full generated diff, and retain the command/API version, argument schema, and request behavior. Check for an existing equivalent fix before making implementation changes.

    Focused regression and scenario coverage

    • Use the existing network unittest structure in test_network_unit_tests.py. Add a source-based, in-memory compilation check for this generated module with invalid-escape warnings treated as errors (SyntaxWarning on Python 3.12+; cover DeprecationWarning where applicable). Do not let an existing .pyc bypass the check.
    • Check the command docstring and parsed example: both Windows path separators and the complete testByCli.cap filename must survive, with no escape-induced control character or whitespace substitution. Validate the example's --storage-location path value without invoking the create operation.
    • Exercise the offline --help scenario, capture stdout and stderr separately, and verify warning-free cold/warm behavior and an intact example. Use the repository's existing test framework; no live Azure resources are required for this regression.
    • Verify regeneration is reproducible and introduces no unintended command/schema/operation changes. The implementation job, not this triage process, performs the focused validation required below.

    Mandatory Codegen execution protocol

    Before editing implementation files, determine whether the affected network command is AAZ-generated. Files under aaz/<profile>/ are generated output and must never be patched directly, including by an AI agent. Check out Azure/aaz beside Azure/azure-rest-api-specs, Azure/aaz-dev-tools, and the downstream repository. API-schema defects start in the specification; command naming, grouping, arguments, API-version selection, help, and examples belong in the durable Azure/aaz command model; non-modelable client behavior belongs in a handwritten subclass or wrapper in custom.py, registered from commands.py. X Engineering Agent creates and promotes the corresponding durable Azure/aaz source pull request before it promotes downstream generated output.

    Follow the Azure CLI repository's Codegen workflow and the aaz-dev setup documentation. Set up the checked-out repositories with azdev setup. Use generate only when importing or redesigning command models from Swagger/TypeSpec. For an existing module whose durable Azure/aaz model has been updated, render that model with regenerate:

    aaz-dev cli regenerate --name network --cli-path <azure-cli>
    
    # New/imported command model only:
    aaz-dev cli generate --spec <specification-name> --module network

    You MUST actually run the generator; do not merely describe it or imitate its output. If the AAZ/specification checkout, local source change, credentials, or generator is unavailable, stop and report the blocker instead of editing generated files. Inspect _aaz_info provenance and the complete regenerated diff, then run focused azdev style, azdev linter, and azdev test validation. For an extension, also update its version and HISTORY.rst, preserve azext_metadata.json compatibility, and let release automation update src/index.json.

    PR title & description format (required)

    This repo enforces a PR format (guide). Please author the PR exactly as follows or CI's Check the Format of Pull Request Title and Content will fail.

    Use this EXACT PR title (copy verbatim, do not reword):

    [Network] Fix #34136: `az network network-watcher packet-capture create`: Escape Windows path backslashes in the help example
    

    Keep the backticks around the command and the Fix #34136: prefix. You may only adjust the wording after the command (the final summary) if the fix changes; the [Network] prefix, issue link, and backticked command must stay.

    Description — follow the PR template and fill in:

    • Link the issue — start the Description with a closing keyword so the PR auto-links and closes it: Fixes #34136.
    • Related command — the az ... command this affects.
    • Description (mandatory) — why the bug happens, what you changed, and the resulting behavior.
    • Testing Guide — example command(s) showing the fix works.
    • History Notes — leave the title to drive the history note, or add extra lines in the same format (component in brackets + the command in backticks), e.g. [Network] `az <command>`: <note>.
    • Keep the template checklist and tick the items you've satisfied.
  4. x-engineering-agent commented on Sep 25, 2026

    @x-engineering-agent
    Contributor

    Implementation Result

    No pull request was opened because the implementation run completed without a validated code change.

    The source analysis remains available above. A maintainer should confirm whether the issue is already resolved on the current target branch or provide the reproduction or root-cause evidence needed for another implementation request.

  5. removed
    questionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that
    on Sep 25, 2026
  6. added this to the Backlog milestone on Sep 25, 2026
  7. microsoft-github-policy-service commented on Sep 28, 2026

    @microsoft-github-policy-service
    Contributor

    🔔 Routing this issue to @Azure/act-quality-productivity-squad.

  8. microsoft-github-policy-service commented on Sep 28, 2026

    @microsoft-github-policy-service
    Contributor

    Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc aznetsuppgithub, @Azure/act-quality-productivity-squad.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Auto-AssignAuto assign by botAzure CLI TeamThe command of the issue is owned by Azure CLI teamNetworkaz network vnet/lb/nic/dns/etc...Service AttentionThis issue is responsible by Azure service team.act-quality-productivity-squadbugThis issue requires a change to an existing behavior in the product in order to be resolved.customer-reportedIssues that are reported by GitHub users external to the Azure organization.

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions