From 991369cebfedb75369a35e855cca414187918c93 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 00:51:19 +0000 Subject: [PATCH 1/3] Initial plan From 737f3d1d22bb73b3f31ec72ecf689f5435c1561c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Apr 2026 00:58:05 +0000 Subject: [PATCH 2/3] Skip empty console messages in JSON output to avoid leading newlines on errors Agent-Logs-Url: https://github.com/Azure/azure-dev/sessions/f5638e5b-3026-4fcf-80e7-24c5b72f97e2 Co-authored-by: JeffreyCA <9157833+JeffreyCA@users.noreply.github.com> --- cli/azd/pkg/input/console.go | 6 ++++++ cli/azd/pkg/input/console_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/cli/azd/pkg/input/console.go b/cli/azd/pkg/input/console.go index d93d3643c44..b5cfcb444ad 100644 --- a/cli/azd/pkg/input/console.go +++ b/cli/azd/pkg/input/console.go @@ -218,6 +218,12 @@ func (c *AskerConsole) IsUnformatted() bool { func (c *AskerConsole) Message(ctx context.Context, message string) { // Disable output when formatting is enabled if c.formatter != nil && c.formatter.Kind() == output.JsonFormat { + // Empty messages are visual separators (blank lines) in text mode. + // In JSON mode they have no semantic value, so skip them. + if message == "" { + return + } + // we call json.Marshal directly, because the formatter marshalls using indentation, and we would prefer // these objects be written on a single line. var obj any = output.EventForMessage(message) diff --git a/cli/azd/pkg/input/console_test.go b/cli/azd/pkg/input/console_test.go index 48b9e595b01..c89789cc1ec 100644 --- a/cli/azd/pkg/input/console_test.go +++ b/cli/azd/pkg/input/console_test.go @@ -368,6 +368,34 @@ func TestAskerConsole_Message_InvalidQuery_FallsBack(t *testing.T) { "invalid query should fall back to full envelope") } +func TestAskerConsole_Message_EmptySkippedInJson(t *testing.T) { + buf := &strings.Builder{} + formatter := &output.JsonFormatter{} + + c := NewConsole( + true, + false, + false, + Writers{Output: writerAdapter{buf}}, + ConsoleHandles{ + Stderr: os.Stderr, + Stdin: os.Stdin, + Stdout: writerAdapter{buf}, + }, + formatter, + nil, + ) + + // An empty message should produce no JSON output (it's just a visual separator in text mode) + c.Message(context.Background(), "") + require.Empty(t, buf.String(), "empty message should not emit any JSON output") + + // A non-empty message should still produce JSON output + c.Message(context.Background(), "hello") + require.NotEmpty(t, buf.String(), "non-empty message should emit JSON output") + require.Contains(t, buf.String(), `"consoleMessage"`) +} + // writerAdapter wraps *strings.Builder to satisfy io.Writer for test purposes. type writerAdapter struct { *strings.Builder From 6cd1f2faef34cab365c25e85614d50e1284879d5 Mon Sep 17 00:00:00 2001 From: Jeffrey Chen Date: Tue, 14 Apr 2026 18:32:18 +0000 Subject: [PATCH 3/3] Clarify comment --- cli/azd/pkg/input/console.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/azd/pkg/input/console.go b/cli/azd/pkg/input/console.go index b5cfcb444ad..02b29a5d9ec 100644 --- a/cli/azd/pkg/input/console.go +++ b/cli/azd/pkg/input/console.go @@ -216,7 +216,7 @@ func (c *AskerConsole) IsUnformatted() bool { // Prints out a message to the underlying console write func (c *AskerConsole) Message(ctx context.Context, message string) { - // Disable output when formatting is enabled + // In JSON mode, emit structured event output instead of plain text. if c.formatter != nil && c.formatter.Kind() == output.JsonFormat { // Empty messages are visual separators (blank lines) in text mode. // In JSON mode they have no semantic value, so skip them.