Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

fix(documents): ignore an empty sourceUpload instead of misrouting the write

merged#2799CedarCopilot

CedarCopilot wants to merge 1 commit into staging from fix/write-document-empty-upload-branch

Live on prod, no production signal yetTimeline and evidence
  1. Opened
    Sep 15, 2026, 1:38 PM
  2. Sep 15, 2026, 1:46 PM
  3. Merged
    Sep 15, 2026, 1:59 PM
  4. Live on prod
    Sep 15, 2026, 1:59 PM
  5. Observed 2 days
    Sep 15, 2026, 1:59 PM
  6. Pipelines steady after this deploy
    Sep 15, 2026, 1:59 PM
  7. Unobserved

    Live on prod, no production signal yet

    Sep 18, 2026, 9:51 AM

Behaviors Libra is checking

Document writes with a sourceUpload object whose contentBase64 is empty are treated as ordinary content writes instead of being misrouted to the upload path and rejected.Inconclusivelow confidence

Verification reached its 130s outer budget before the verifier returned. Libra is keeping this intent verifying until the next check.

prod, checked Sep 18, 2026, 9:51 AM

Libra has verdicts on 0 of 1 tracked behaviors on prod; 1 is still being checked. Libra checks hourly for 3 days after each deploy.

Summary

  • write-document's generic-upload branch gated on if (input.sourceUpload), which is truthy for { filename: '', mimeType: '', contentBase64: '' } , an empty-but-present object, not an actual upload request.
  • The same tool-calling paths that were sending an empty sourceEmailAttachment on ordinary writes (fixed in #2761's sibling commit 2e5e41920) also send this shape on sourceUpload, so the write got misrouted into the upload branch, decoded zero bytes from the empty contentBase64, and failed with "Decoded upload is empty" , the real content (e.g. a daily-agenda doc) was never saved.
  • Gate on input.sourceUpload?.contentBase64 instead, so an empty upload reference is treated as absent and the write proceeds normally.

Traced from agent_tool_calls.id = 36f96438-927c-4a9d-8353-d627585447e9: this morning's daily-agenda orchestrator run sent a full agenda in content alongside an empty sourceUpload, hit this branch, failed, and the run gave up (mark-execution-as-failed) instead of saving the agenda. A DB check shows 9 write-document calls hit this exact error in the last 24 hours, across 3 different subagents/users.

Test plan

  • pnpm --filter @zero/server exec vitest run src/mastra/tools/document/__tests__/writeDocumentTool.test.ts , 10 passed, including new regression test for the empty-sourceUpload case.
  • Typecheck on the changed file is clean.

🤖 Generated with Claude Code

Greptile Summary

This PR corrects generic-upload routing for ordinary document writes that include an empty sourceUpload placeholder.

  • Gates upload handling on non-empty contentBase64 rather than object presence.
  • Adds a focused regression test proving that agenda content reaches the normal guarded writer.
  • The implementation addresses the reported empty-string failure path, but the new test contains casts prohibited by the repository’s TypeScript rules.

Confidence Score: 4/5

The behavioral fix appears sound, but the explicit repository prohibition on TypeScript casts must be satisfied before merging.

The changed branch correctly restores normal writes for the observed empty placeholder, and the regression test would fail on the previous implementation; the only accepted concern is the test’s use of prohibited casts.

Files Needing Attention: apps/server/src/mastra/tools/document/tests/writeDocumentTool.test.ts

Important Files Changed

FilenameOverview
apps/server/src/mastra/tools/document/writeDocumentTool.tsCorrectly treats the observed empty-string upload placeholder as absent so ordinary document content reaches the durable write path.
apps/server/src/mastra/tools/document/tests/writeDocumentTool.test.tsAdds causally effective regression coverage, but introduces three TypeScript casts prohibited by the repository guide.
Prompt To Fix All With AI
### Issue 1
apps/server/src/mastra/tools/document/__tests__/writeDocumentTool.test.ts:370-372
**Prohibited TypeScript Casts**

This test adds three explicit type assertions: two `as never` argument casts and a cast for the result shape. The repository requires typed inputs and inferred result types instead of casts that silence TypeScript errors. This requirement must be satisfied before merging.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(documents): ignore an empty sourceUp..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Context used (4)

Show production surfaces and changed-file mapping

Production surfaces

Libra has not measured any production surfaces for this change yet.

Changed files → surfaces

  • apps/server/src/mastra/tools/document/__tests__/writeDocumentTool.test.tsno production surface mapped
  • apps/server/src/mastra/tools/document/writeDocumentTool.tsno production surface mapped