Repository navigation
fix: prevent first-run tool check recursion and JSON contamination - #8084
Conversation
…zure#8052) Replace group-based isWorkflowCommand() with an explicit allowlist of workflow commands (init, up, provision, deploy, down, publish, build, package, restore). This excludes utility commands like 'extension' from triggering the first-run tool check, preventing recursive subprocess spawning when DetectAll() calls 'azd extension list'. As defense-in-depth, set AZD_SKIP_FIRST_RUN=true and NO_COLOR=1 in the child process environment when detectLibrary() invokes the command runner. This prevents recursion even if command scoping changes in the future and suppresses ANSI escape codes that would break JSON parsing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Prevents the first-run tool check from re-triggering itself via azd extension list subprocesses and avoids ANSI output contaminating JSON parsing.
Changes:
- Restricts “workflow command” detection to an explicit allowlist to avoid running first-run checks on utility commands (e.g.,
extension). - Adds environment variables to the
azd extension listchild process to skip first-run checks and disable color output. - Adds a unit test to validate the child process environment variables are set.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| cli/azd/pkg/tool/detector.go | Forces AZD_SKIP_FIRST_RUN and NO_COLOR on the library detection subprocess. |
| cli/azd/pkg/tool/detector_test.go | Adds a test ensuring env vars are propagated to the subprocess. |
| cli/azd/cmd/root.go | Replaces group-based workflow detection with an explicit allowlist to prevent recursion. |
- Add clarifying comment on Env field in detectLibrary() explaining
that appendEnv() merges with current environment
- Use Cobra's Name() instead of manual Use string parsing
- Switch workflowCommands from map[string]bool to map[string]struct{}
to match codebase set conventions
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The isWorkflowCommand() allowlist prevents the first-run middleware from running on utility commands like 'extension list', which eliminates the recursion. The env var defense-in-depth layer is unnecessary complexity. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Azure Dev CLI Install InstructionsInstall scriptsMacOS/Linux
bash: pwsh: WindowsPowerShell install MSI install Standalone Binary
MSI
Documentationlearn.microsoft.com documentationtitle: Azure Developer CLI reference
|
…8084) * fix: prevent first-run tool check recursion and JSON contamination (#8052) Replace group-based isWorkflowCommand() with an explicit allowlist of workflow commands (init, up, provision, deploy, down, publish, build, package, restore). This excludes utility commands like 'extension' from triggering the first-run tool check, preventing recursive subprocess spawning when DetectAll() calls 'azd extension list'. As defense-in-depth, set AZD_SKIP_FIRST_RUN=true and NO_COLOR=1 in the child process environment when detectLibrary() invokes the command runner. This prevents recursion even if command scoping changes in the future and suppresses ANSI escape codes that would break JSON parsing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: address PR review feedback for tool first-run recursion fix - Add clarifying comment on Env field in detectLibrary() explaining that appendEnv() merges with current environment - Use Cobra's Name() instead of manual Use string parsing - Switch workflowCommands from map[string]bool to map[string]struct{} to match codebase set conventions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: tighten mock matcher in env vars test to validate args Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor: remove detector env vars, rely on command scoping allowlist The isWorkflowCommand() allowlist prevents the first-run middleware from running on utility commands like 'extension list', which eliminates the recursion. The env var defense-in-depth layer is unnecessary complexity. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: therealjohn <1501196+therealjohn@users.noreply.github.com>
Fixes #8052 — Prevents the first-run tool check from spawning recursive
azd extension listsubprocesses and contaminating JSON stdout.Problem
When the first-run tool check middleware runs, it calls
manager.DetectAll()which spawnsazd extension list --installed --output jsonas a child OS process to detect installed extensions. This child process re-triggers the same first-run tool check because it is a new OS process without theIsChildActioncontext marker, causing:json.Unmarshalwithinvalid character ''\\x1b''Fix
Narrow
isWorkflowCommand()scope (root.go)Replaced the broad group-based predicate (which matched all
CmdGroupBetacommands includingextension) with an explicit allowlist of workflow commands:init,up,provision,deploy,down,publish,build,package,restoreCommands like
extension,auth,config,env,hooks,infra,template,monitor,add, andupdateno longer trigger the first-run check. This is intentional — the first-run tool check and update notifications are only valuable for primary workflow commands that interact with Azure resources.Testing