Add --fail-on-prompt flag for strict non-interactive mode#7394
Add --fail-on-prompt flag for strict non-interactive mode#7394
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a new strict non-interactive prompt mode for azd via a --fail-on-prompt global flag, and updates agent auto-detection to default agent sessions into this strict mode so that interactive decisions never silently fall back to defaults.
Changes:
- Adds
GlobalCommandOptions.FailOnPromptand a new--fail-on-promptglobal flag (implies--no-prompt), plus agent auto-detection now enables strict mode by default. - Extends the input prompting subsystem (
NewConsole/NewAsker) with a fail-fast asker (askOneFailOnPrompt) and updates call sites/tests accordingly. - Updates CLI help snapshots and Fig completion spec fixtures to include the new global flag.
Reviewed changes
Copilot reviewed 103 out of 103 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| cli/azd/pkg/input/console.go | Adds failOnPrompt plumbing to the console and asker construction. |
| cli/azd/pkg/input/console_test.go | Updates console constructor calls for the new parameter. |
| cli/azd/pkg/input/console_helpers_test.go | Updates test helper console construction for the new parameter. |
| cli/azd/pkg/input/asker.go | Adds failOnPrompt mode and askOneFailOnPrompt implementation. |
| cli/azd/pkg/input/asker_test.go | Adds/updates tests for NewAsker signature and fail-on-prompt behavior. |
| cli/azd/internal/vsrpc/server_session.go | Updates console construction for new NewConsole signature. |
| cli/azd/internal/repository/infra_confirm_test.go | Updates console construction for new NewConsole signature. |
| cli/azd/internal/repository/detect_confirm_test.go | Updates console construction for new NewConsole signature. |
| cli/azd/internal/repository/app_init_test.go | Updates console construction for new NewConsole signature. |
| cli/azd/internal/global_command_options.go | Adds FailOnPrompt to global command options. |
| cli/azd/extensions/azure.coding-agent/internal/cmd/coding_agent_config.go | Updates extension console construction for new NewConsole signature. |
| cli/azd/extensions/azure.ai.finetune/internal/cmd/init.go | Updates extension console construction for new NewConsole signature. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/init.go | Updates extension console construction for new NewConsole signature. |
| cli/azd/cmd/testdata/TestUsage-azd.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-x.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-version.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-up.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-template.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-template-source.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-template-source-remove.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-template-source-list.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-template-source-add.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-template-show.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-template-list.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-show.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-restore.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-publish.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-provision.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-pipeline.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-pipeline-config.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-package.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-monitor.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-mcp.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-mcp-start.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-init.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-infra.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-infra-generate.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-hooks.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-hooks-run.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-extension.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-extension-upgrade.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-extension-uninstall.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-extension-source.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-extension-source-validate.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-extension-source-remove.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-extension-source-list.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-extension-source-add.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-extension-show.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-extension-list.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-extension-install.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-env.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-env-set.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-env-set-secret.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-env-select.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-env-remove.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-env-refresh.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-env-new.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-env-list.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-env-get-values.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-env-get-value.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-env-config.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-env-config-unset.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-env-config-set.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-env-config-get.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-down.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-deploy.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-demo.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-copilot.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-copilot-consent.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-copilot-consent-revoke.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-copilot-consent-list.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-copilot-consent-grant.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-config.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-config-unset.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-config-show.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-config-set.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-config-reset.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-config-options.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-config-list-alpha.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-config-get.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-concurx.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-completion.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-completion-zsh.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-completion-powershell.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-completion-fish.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-completion-fig.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-completion-bash.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-coding-agent.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-auth.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-auth-status.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-auth-logout.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-auth-login.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-appservice.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-ai.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-ai-models.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-ai-finetuning.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-ai-agent.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestUsage-azd-add.snap | Help snapshot updated to include --fail-on-prompt. |
| cli/azd/cmd/testdata/TestFigSpec.ts | Fig completion spec fixture updated for --fail-on-prompt. |
| cli/azd/cmd/external_prompt_test.go | Passes FailOnPrompt into console construction for external prompt tests. |
| cli/azd/cmd/container.go | Wires FailOnPrompt from root options into input.NewConsole. |
| cli/azd/cmd/auto_install.go | Registers/parses --fail-on-prompt and updates agent detection behavior. |
| cli/azd/cmd/auto_install_test.go | Extends flag parsing tests to validate FailOnPrompt and implication rules. |
wbreza
left a comment
There was a problem hiding this comment.
Code Review — PR #7394
Add --fail-on-prompt flag for strict non-interactive mode by @spboyer
DRY Assessment
Of 111 files changed, 86 are snapshot regenerations and 6 are extension go.mod/go.sum churn — only 19 files contain real changes. The core feature pattern is clean (follows existing askOneNoPrompt precedent), but there are DRY issues in the error messages and parameter threading.
Findings
| Priority | Count |
|---|---|
| High | 2 |
| Medium | 4 |
| Low | 3 |
| Total | 9 |
🔴 [HIGH] Extension go.mod files contain local replace directives
Files: extensions/azure.ai.agents/go.mod, extensions/azure.ai.finetune/go.mod, extensions/azure.coding-agent/go.mod
All three add replace github.com/azure/azure-dev/cli/azd => ../../ — these are local development artifacts that break CI and anyone cloning the repo. Per AGENTS.md: "Do NOT commit any go.mod/go.sum files in cli/azd/extensions/."
Fix: git checkout main -- cli/azd/extensions/*/go.mod cli/azd/extensions/*/go.sum
🔴 [HIGH] Error messages duplicated 15× across 3 files
Files: pkg/input/asker.go, internal/grpcserver/prompt_service.go, pkg/prompt/prompt_service.go
The string "interactive prompt not allowed in strict mode" appears in 15 places with minor variations. If the wording ever needs updating (i18n, adding a docs link), it must change in 15 places.
Fix: Extract 2 error helpers:
func ErrFailOnPrompt(message string) error { ... }
func ErrFailOnPromptWithOptions(message string, options []string) error { ... }🟡 [MEDIUM] Positional bool explosion in NewConsole/NewAsker
NewConsole(noPrompt, failOnPrompt, isTerminal, ...) — three consecutive unlabeled bools. Consider an options struct for future extensibility.
🟡 [MEDIUM] askOneFailOnPrompt type switch collapsible
4 of 6 cases produce the same error format. Could be collapsed to 2 cases using the error helpers above.
🟡 [MEDIUM] FailOnPrompt → NoPrompt invariant not enforced in NewConsole
The implication is only enforced in ParseGlobalFlags. A caller constructing NewConsole directly with failOnPrompt=true, noPrompt=false creates an inconsistent state.
🟡 [MEDIUM] Missing test for --fail-on-prompt=false with agent detection
No test verifies that an agent can explicitly disable strict mode while keeping no-prompt.
🟢 [LOW] Agent auto-detection behavior change
Agent-detected sessions now get FailOnPrompt instead of just NoPrompt. This is the intended design (agents adapt by retrying with correct flags), but worth documenting in CHANGELOG.md.
�� [LOW] WaitForEnter redundant failOnPrompt check
c.noPrompt || c.failOnPrompt — the second condition is redundant if the invariant is enforced.
🟢 [LOW] Extension code changes are mechanical but avoidable
Three extension .go files needed false parameter additions — an options struct would prevent future churn.
What's Done Well
- Clean architecture —
askOneFailOnPromptfollows the existingaskOneNoPromptpattern perfectly. New asker selected at construction, not conditional injection into every prompt method - Comprehensive tests — table-driven tests for all 5 prompt types plus flag parsing/agent detection matrix
- gRPC coverage —
prompt_service.goensures extensions via gRPC also respectFailOnPrompt - Context-specific errors in
pkg/prompt/— subscription, location, resource group prompts give specific, actionable guidance (e.g., "use --subscription or azd config set defaults.subscription"). This is exactly what LLM agents need --fail-on-prompt implies --no-prompt— sound design, no invalid flag combinations
Overall Assessment: Comment — the feature design is solid and the core pattern is clean. The go.mod replace directives need removal before merge, and the 15× error message duplication should be consolidated.
Review performed with GitHub Copilot CLI
jongio
left a comment
There was a problem hiding this comment.
Add --fail-on-prompt flag for strict non-interactive mode by @spboyer
What: Adds a --fail-on-prompt global flag that errors immediately on any interactive prompt - even when defaults exist. Agent-detected sessions now get this stricter mode by default.
Why: --no-prompt silently uses defaults, masking decisions from LLM agents. Fail-on-prompt gives agents explicit, actionable errors with the exact flag or env var to provide.
Assessment: Clean implementation following the established askOneNoPrompt pattern. Core design is sound - asker selection at construction, not conditional injection at every prompt site. @wbreza's review already identified the main issues (go.mod replace directives, error duplication, positional bool threading). Two test coverage gaps below.
| Category | Critical | High | Medium | Low |
|---|---|---|---|---|
| Tests | 0 | 0 | 2 | 0 |
Test coverage estimate:
- Well covered:
askOneFailOnPromptfor Input/Select/Confirm/MultiSelect; flag parsing + agent detection matrix;NewAskerselection logic; backward compat of--no-prompt - Gaps:
*survey.Passwordin fail-on-prompt tests; gRPCprompt_service.goFailOnPrompt behavior (4 methods, all untested);--fail-on-prompt=falsewith agent detection (noted by @wbreza)
What's done well:
askOneFailOnPromptmirrorsaskOneNoPromptperfectly - same structure, closure selection at construction- Context-specific errors in
pkg/prompt/give agents exactly what they need (flag names, config commands) --fail-on-prompt implies --no-promptprevents invalid flag combinations- Agent detection respects explicit flag overrides in both directions
2 inline comments below.
jongio
left a comment
There was a problem hiding this comment.
2 new commits since previous review - both look correct (gofmt fix + NewGitHubCli API adaptation).
New finding:
- pkg/input/asker.go:49,64 + grpcserver/prompt_service.go:98,158 - em dashes (U+2014) in error strings cause mojibake on some terminals
Previous review findings from @wbreza and @jongio are still open.
636832d to
7ac0474
Compare
- Add --fail-on-prompt global flag for strict non-interactive mode - When active, all prompts fail with actionable errors even if defaults exist - Auto-enable when LLM agent is detected (replaces silent default behavior) - --fail-on-prompt implies --no-prompt - --no-prompt alone retains backward-compatible default-using behavior Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…d type - Add FailOnPrompt checks before NoPrompt branches in prompt_service.go (subscription, location, resource group, resource selection) - Add FailOnPrompt checks in gRPC prompt_service.go (Confirm, Select, MultiSelect, Prompt) - Add *survey.Password case to askOneFailOnPrompt with prompt message - All strict-mode errors include actionable guidance Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ives - Break 144-char line in container.go to fit 125-char lll limit - Add replace directives in extension go.mod files so they can compile against the updated NewConsole/NewAsker signatures Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…xternal prompt guard - Add *survey.Password case to askOneFailOnPrompt with message in error. - Replace Unicode em dashes with ASCII in all fail-on-prompt error strings (4 occurrences across asker.go and prompt_service.go). - Add Password_WithMessage test case to asker fail-on-prompt table. - Add FailOnPrompt test cases to gRPC prompt_service_test.go. - Short-circuit external prompting when failOnPrompt is set on console. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Run go mod tidy on all 3 extensions to add missing go.sum entries for new core dependencies (azsecrets, armkeyvault, etc.). - Add PromptAiDeployment, PromptAiModel, PromptAiLocationWithQuota, and PromptAiModelLocationWithQuota to MockPromptServiceClient to match the updated PromptServiceClient interface. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add tests for PromptSubscription, PromptLocation, PromptResourceGroup, PromptSubscriptionResource, and PromptResourceGroupResource covering the FailOnPrompt error paths with actionable error messages. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
61ddd4d to
512d8ca
Compare
Azure Dev CLI Install InstructionsInstall scriptsMacOS/Linux
bash: pwsh: WindowsPowerShell install MSI install Standalone Binary
MSI
Documentationlearn.microsoft.com documentationtitle: Azure Developer CLI reference
|
Summary
Adds a
--fail-on-promptglobal flag that causes azd to fail immediately with a clear, actionable error whenever any interactive prompt is encountered — regardless of whether a default value exists.This is now the automatic default behavior when azd detects it is being called by an LLM agent (Claude Code, GitHub Copilot CLI, Cursor, Gemini CLI, OpenCode, etc.).
Motivation
The existing
--no-promptflag silently uses default values when available. For LLM agents, this masks decisions — the tool proceeds with a default that may not be what was intended. Fail-on-prompt ensures agents get explicit errors telling them exactly what flag or env var to provide.Changes
GlobalCommandOptions.FailOnPrompt— new field in the options struct--fail-on-promptflag — registered as a global flag; implies--no-promptaskOneFailOnPrompt()— new asker that always returns actionable errors listing the prompt question and available optionsNoPromptandFailOnPrompt(previously only setNoPrompt)--no-promptalone — retains backward-compatible behavior (uses defaults silently)NewAsker/NewConsole— acceptfailOnPromptparameterBackward Compatibility
--no-promptbehavior is unchanged — it still silently uses defaults--no-promptto get the old silent-default behavior even when an agent is detectedFixes #7390