From 1dcdd01378e8def42840e1fc9b62f369c1a6963c Mon Sep 17 00:00:00 2001 From: Hongming Wang Date: Sat, 18 Apr 2026 07:45:14 -0700 Subject: [PATCH] fix(scheduler): strip CRLF from cron prompts on insert/update (closes #958) Windows CRLF in org-template prompt text caused empty agent responses and phantom-producing detection. Strips \r at the handler level before DB persist, plus a one-time migration to clean existing rows. Co-Authored-By: Claude Opus 4.6 (1M context) --- workspace-server/internal/handlers/schedules.go | 11 +++++++++++ .../migrations/033_strip_crlf_cron_prompts.up.sql | 3 +++ 2 files changed, 14 insertions(+) create mode 100644 workspace-server/migrations/033_strip_crlf_cron_prompts.up.sql diff --git a/workspace-server/internal/handlers/schedules.go b/workspace-server/internal/handlers/schedules.go index c11d74cc..555a5898 100644 --- a/workspace-server/internal/handlers/schedules.go +++ b/workspace-server/internal/handlers/schedules.go @@ -5,6 +5,7 @@ import ( "encoding/json" "log" "net/http" + "strings" "time" "github.com/gin-gonic/gin" @@ -96,6 +97,10 @@ func (h *ScheduleHandler) Create(c *gin.Context) { return } + // Strip CRLF from prompts — org-template files committed on Windows + // inject \r\n, causing empty agent responses (issue #958). + body.Prompt = strings.ReplaceAll(body.Prompt, "\r", "") + if body.Timezone == "" { body.Timezone = "UTC" } @@ -161,6 +166,12 @@ func (h *ScheduleHandler) Update(c *gin.Context) { return } + // Strip CRLF from prompt if provided (issue #958). + if body.Prompt != nil { + clean := strings.ReplaceAll(*body.Prompt, "\r", "") + body.Prompt = &clean + } + // If cron_expr or timezone changed, revalidate and recompute next_run var nextRunAt *time.Time if body.CronExpr != nil || body.Timezone != nil { diff --git a/workspace-server/migrations/033_strip_crlf_cron_prompts.up.sql b/workspace-server/migrations/033_strip_crlf_cron_prompts.up.sql new file mode 100644 index 00000000..06a547c4 --- /dev/null +++ b/workspace-server/migrations/033_strip_crlf_cron_prompts.up.sql @@ -0,0 +1,3 @@ +-- Issue #958: Strip CRLF from cron prompts inserted from Windows org-template files. +-- Carriage returns cause empty agent responses and phantom-producing detection. +UPDATE workspace_schedules SET prompt = REPLACE(prompt, E'\r', '') WHERE prompt LIKE E'%\r%';