Skip to content

[Bug]: Windows Paths with \n Sequences Are Corrupted When Sent from WebUI #7968

@quic-zhanweiw

Description

@quic-zhanweiw

Problem Description
When a user inputs a Windows file path containing \n sequences (like C:\Work\nxxx\README.md) through the WebUI, the path gets corrupted by the time it reaches the model service. The backslash-n sequences (\n) are being converted to actual newline characters, breaking the path.

Example:

Input: C:\Work\nxxx\README.md
Received: C:\Work xxx\README.md (with actual newlines replacing \n)

Root Cause
The issue is in normalizeInboundTextNewlines() function, which was converting literal \n sequences to newlines:

export function normalizeInboundTextNewlines(input: string): string {
return input.replaceAll("\r\n", "\n").replaceAll("\r", "\n").replaceAll("\n", "\n");
// ^^^^^^^^^^^^^^^^^^^^^^^^
// This breaks Windows paths!
}
This function is called on all inbound text from various channels (see /src/auto-reply/reply/inbound-context.ts:5), including WebUI messages.

Proposed Solution
Remove the .replaceAll("\n", "\n") operation to preserve literal backslash-n sequences:

export function normalizeInboundTextNewlines(input: string): string {

  • return input.replaceAll("\r\n", "\n").replaceAll("\r", "\n").replaceAll("\n", "\n");
  • // Normalize actual newline characters (CR+LF and CR to LF)
  • // Do NOT replace literal backslash-n sequences (\n) as they may be part of Windows paths
  • // like C:\nxxx or legitimate escaped sequences in user input
  • return input.replaceAll("\r\n", "\n").replaceAll("\r", "\n");
    }
    This fix resolves the Windows path corruption issue.

Uncertainty & Request for Review
I'm not certain whether this change might affect other functionality. The original code appears to have been designed to decode literal \n escape sequences into newlines for some use case, but I cannot determine:

Why was \n → \n conversion originally needed? Was it for a specific messaging channel or input format?
Are there legitimate cases where users need to send literal \n sequences that should be converted to newlines?
Could this break existing workflows or tests?
I noticed there's a test case in inbound.test.ts:

it("decodes literal \n to newlines when no real newlines exist", () => {
expect(normalizeInboundTextNewlines("a\nb")).toBe("a\nb");
});
This test would fail with my fix, suggesting the \n conversion was intentional. However, this conflicts with Windows path handling.

Questions for Maintainers
Should we differentiate between Windows paths and intentional escape sequences?
Is there a better place to handle newline normalization that wouldn't affect file paths?
Should the WebUI or specific channels handle path escaping differently?
Any guidance on the intended behavior and potential side effects would be greatly appreciated!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions