Skip to content

fix(server): long scheduled-task titles no longer end in a broken character - #28831

Open
only21mil wants to merge 1 commit into
pingdotgg:mainfrom
only21mil:fix/audit-m142
Open

only21mil wants to merge 1 commit into
pingdotgg:mainfrom
only21mil:fix/audit-m142

Conversation

@only21mil

Copy link
Copy Markdown
Contributor

Problem

When an agent schedules a task over MCP without a title, the server names it after the prompt's first line, cut to 80 UTF-16 code units. If an emoji or other character outside the Basic Multilingual Plane straddles unit 80, the cut keeps only its high surrogate. The saved title then ends in �, and that character is stored, so it shows on every client that lists the task.

To reproduce: have an agent call schedule_task with no title and a prompt whose first line is 79 ASCII characters followed by 🚀. Settings → Scheduled tasks shows the title ending in �.

Change

After the 80-unit cut, drop a trailing lone high surrogate. This is the same idiom GitVcsDriverCore already uses for worktree directory names. The 80-unit limit, explicit titles and the Scheduled task fallback for a blank first line are unchanged. A first line that is nothing but a lone surrogate now falls back to Scheduled task rather than saving the surrogate.

Scope and approval

There is no issue or discussion. This is a very small, focused fix for an obvious bug: a truncation that splits a surrogate pair and saves a broken character. It changes one expression in the MCP scheduleTask default-title path. It does not change title limits or add grapheme-aware truncation.

Verification

  • vp test run apps/server/src/mcp/OrchestratorMcpService.test.ts -t "titles": a new table covering a long ASCII line, an emoji split by the limit, an emoji ending exactly at the limit, a blank first line and an explicit title. With the source change reverted, only "an emoji split by the limit" fails, receiving a title ending in \uD83D. With the change, all pass.
  • vp run check:changed 1d626d02d95f9a2343553f6498037ee82290d304: format, lint, knip, typecheck and tests all pass.
  • Real UI: in an isolated dev server with no seeded data, a Claude Haiku 5.5 thread called schedule_task once with no title. Its prompt's first line puts 🚀 at units 79–80. Each client opened the task from Settings → Scheduled tasks (the list on web and desktop, the task editor on Android and iOS), once on the base server and once on this change. A read-only SQLite check found the base stored title ending in U+FFFD and this change's title ending in summary .

Web, base server: the title ends in a replacement character.

Web scheduled tasks, base server

Web, this change: the title ends after "summary".

Web scheduled tasks, this change

Desktop (Electron dev app), base server: the title ends in a replacement character.

Desktop scheduled tasks, base server

Desktop, this change: the title ends after "summary".

Desktop scheduled tasks, this change

Android emulator, task editor scrolled to the end of Name, base server: the name ends in a replacement character.

Android scheduled tasks, base server

Android, this change: the name ends after "summary".

Android scheduled tasks, this change

iOS simulator, task editor with the Name caret at the end, base server: the name ends in a replacement character.

iOS scheduled tasks, base server

iOS, this change: the name ends after "summary".

iOS scheduled tasks, this change

Not checked: other browsers; tunnel and relay connection modes, though the title is server data and travels unchanged; iPad layout. A cut that lands just after a space still leaves that trailing space, as it did before; this change does not alter that.

Prior PRs

Generated with Claude Opus 5.5 and GPT-6.1 Terra and GPT-6.1 Sol in T3 Code Nightly

A title derived from an agent's schedule_task prompt is cut at 80 UTF-16
code units, which can split a surrogate pair and leave a lone high
surrogate that renders as a replacement character. Drop that dangling
half after the cut, keeping the 80-unit limit, explicit titles and the
"Scheduled task" fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Nov 1, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — This prevents broken characters in automatically generated scheduled-task titles without changing task execution or explicit titles. Because it changes the default title generated when no title is supplied, human review is required.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 965291e and b1932b2.

Files selected for processing: 2
  • apps/server/src/mcp/OrchestratorMcpService.test.ts
  • apps/server/src/mcp/OrchestratorMcpService.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.

Walkthrough

Scheduled-task titles derived from prompts now use a trimmed first line capped at 80 UTF-16 code units, with a trailing high surrogate removed when needed. Tests record complete upsert inputs and cover title handling and workspace-strategy selection.

Changes: Scheduled-task title handling

Layer / File(s) Summary
Title derivation and scheduled-task tests
apps/server/src/mcp/OrchestratorMcpService.ts, apps/server/src/mcp/OrchestratorMcpService.test.ts
Prompt-derived titles use the trimmed first line, are limited to 80 code units, and avoid ending on a high surrogate. Explicit titles remain unchanged, and an empty derived title falls back to "Scheduled task". Tests record complete upsert inputs and check title and workspace-strategy values.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: juliusmarminge

Merge Risk: Minimal · up to b1932

The scheduled-task title fix is mergeable with no identified correctness, security, integrity, or availability risk.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely describes the primary fix: preventing long scheduled-task titles from ending with a broken character.
Description check Passed The description covers the problem, expected behavior, reproduction steps, implementation, scope justification, focused tests, broader verification, observed results, and known limitations.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Finishing Touches
Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant