CedarCopilot wants to merge 1 commit into staging from fix/config-read-mastra-output-envelope
Live on prod, no production signal yet
Strict CloudWatch fallback found 1 prod failure log lines for mirror.upsertEmailThread failed (Failed query: \n UPDATE crm_thread_labels tl\n SET latest_message_at = t.latest_message_at\n FROM crm_email_threads t\n WHERE t.thread_id = tl.thread_id\n AND tl.thread_id = $1\n AND.
Verification reached its 120s wall-clock budget before a tied verdict. Libra is keeping this intent verifying until the next check.
internal_only
internal_only
internal_only
Libra has verdicts on 0 of 2 tracked behaviors on prod; 2 are still being checked. Libra checks hourly for 3 days after each deploy.
config-read's list-fields action was failing with MCP error -32602: Output validation error: ... path: ["success"], message: "Required" , an opaque error that pointed nowhere near the actual problem.Tool.execute() validates a family tool's return value against its own outputSchema internally, and on a mismatch it doesn't throw , it silently returns an {error: true, message, validationErrors} envelope in place of the tool's real result. server.ts's toCallToolResult forwarded that envelope unchanged as structuredContent with no isError flag, so the MCP SDK then ran its own outputSchema check against the error object and failed on the missing success field.FieldOptionDataSchema.color was a required z.string(), but CustomFieldDefinition.options[].color is stored in a jsonb column with no runtime enforcement of the TS type , a legacy/hand-edited field option missing color failed Mastra's internal validation.server.ts: toCallToolResult now detects Mastra's internal validation-failure envelope and converts it into a proper isError CallToolResult with a legible message, instead of letting the SDK reject it with a confusing schema error.config-tool-shared.ts: FieldOptionDataSchema.color is now optional, matching the reality of stored field options.server.test.ts: pins the envelope→isError translation, confirms a real {success, ...} result still passes through unchanged, and confirms a real result carrying its own domain-level error field alongside success isn't misclassified.Went through a thermo-nuclear code review pass (dependency direction, false-positive risk against every other family tool's output schema, file size, type cleanliness) before opening.
pnpm --filter @zero/server exec vitest run src/mastra/mcp/external/__tests__/server.test.ts src/mastra/tools/config/__tests__/configTool.test.ts , 119 passedpnpm --filter @zero/server run types , cleanpnpm deps:check , no violations🤖 Generated with Claude Code
https://claude.ai/code/session_01BJ92k9jHt3CmmqX1dji4Zc
This PR improves external MCP error handling and aligns config field-option validation with persisted legacy data.
error property.The PR appears safe to merge, with the validation-envelope translation and legacy color handling covered by focused regression tests.
No actionable failure remains: the guard distinguishes current legitimate family-tool results, the MCP error shape matches existing server conventions, and optional color reflects persisted legacy data without breaking repository consumers.
| Filename | Overview |
|---|---|
| apps/server/src/mastra/mcp/external/server.ts | Detects Mastra output-validation envelopes and converts them to conventional MCP error results without misclassifying normal family-tool output. |
| apps/server/src/mastra/mcp/external/tests/server.test.ts | Adds focused regression tests for envelope translation and the principal false-positive cases. |
| apps/server/src/mastra/tools/config/config-tool-shared.ts | Makes field-option color optional so the output schema reflects legacy JSONB records that legitimately omit it. |
Libra has not measured any production surfaces for this change yet.