Skip to content

v5.2.2

Choose a tag to compare

@github-actions github-actions released this 19 Aug 07:52
· 76 commits to main since this release
39eacd9

Patch Changes

  • 8fd15f9: Stop returning bare 500s when a channel's stored config can't be parsed, and let a full save repair it.

    Every channel service parsed conv_channels.config with a bare .parse(), so a row that doesn't satisfy its stored schema threw a raw ZodError out of the handler and surfaced as an uninformative Internal server error. ConvService.importConv writes config: {} on every imported channel by design — the operator is told to "re-enter them on this server" — so the documented recovery path ran straight into this.

    Stored configs now go through a shared parseStoredConfig, which throws a transport-free ChannelConfigInvalidError carrying code: 'conv_channel_config_invalid' and the offending field paths. A controller-scoped interceptor maps it to a 500 at the HTTP boundary: a corrupt stored config is a server-side fault the caller cannot fix by changing the request, which is the same split nestjs-zod makes between request validation (400) and server-side serialization failures (500). The MCP dispatcher already surfaces the message, so agents get the coded string and the dashboard translates via code. Applied to all five channel kinds — email, Vapi, Twilio, MessageBird and Threll.

    EmailService.updateChannel additionally falls back to building the config from the submitted input when the stored one won't parse, so saving a complete configuration repairs the row instead of bouncing off it. The vendor services deliberately do not get that fallback: their merges read input.config?.x ?? prev.x, so rebuilding from a partial input would silently drop settings — they surface the error instead.

    Separately, the four vendor admin providers parsed incoming config with a bare ConfigSchema.parse(input.config), turning ordinary bad input into a 500 as well. That boundary is genuinely client-side, so it now throws a 400 naming the offending fields, matching the validatePendingConfig helper already sitting a few lines below each one.

    • @getmunin/inspector-app@5.2.2
    • @getmunin/core@5.2.2
    • @getmunin/db@5.2.2
    • @getmunin/types@5.2.2
    • @getmunin/mcp-toolkit@5.2.2
    • @getmunin/agent-runtime@5.2.2
    • @getmunin/emails@5.2.2
  • 8fd15f9: Stop returning bare 500s when a channel's stored config can't be parsed, and let a full save repair it.

    Every channel service parsed conv_channels.config with a bare .parse(), so a row that doesn't satisfy its stored schema threw a raw ZodError out of the handler and surfaced as an uninformative Internal server error. ConvService.importConv writes config: {} on every imported channel by design — the operator is told to "re-enter them on this server" — so the documented recovery path ran straight into this.

    Stored configs now go through a shared parseStoredConfig, which throws a transport-free ChannelConfigInvalidError carrying code: 'conv_channel_config_invalid' and the offending field paths. A controller-scoped interceptor maps it to a 500 at the HTTP boundary: a corrupt stored config is a server-side fault the caller cannot fix by changing the request, which is the same split nestjs-zod makes between request validation (400) and server-side serialization failures (500). The MCP dispatcher already surfaces the message, so agents get the coded string and the dashboard translates via code. Applied to all five channel kinds — email, Vapi, Twilio, MessageBird and Threll.

    EmailService.updateChannel additionally falls back to building the config from the submitted input when the stored one won't parse, so saving a complete configuration repairs the row instead of bouncing off it. The vendor services deliberately do not get that fallback: their merges read input.config?.x ?? prev.x, so rebuilding from a partial input would silently drop settings — they surface the error instead.

    Separately, the four vendor admin providers parsed incoming config with a bare ConfigSchema.parse(input.config), turning ordinary bad input into a 500 as well. That boundary is genuinely client-side, so it now throws a 400 naming the offending fields, matching the validatePendingConfig helper already sitting a few lines below each one.

  • 5ea99ce: Pin the submit error in the email channel dialog to the footer instead of leaving it in the gap below the scroll area.

    The email channel dialog is the only one that scrolls an inner region rather than the whole popup, so its FormError rendered as a detached inset box wedged between the scroll container and the footer — misaligned against both neighbours' negative-margin bleeds, and with no spacing from the fields above. FormError now takes a pinned variant that drops the box for a rule-soft separator inset to the content width, on the same 16px/16px rhythm as the rule under the dialog header, so the error reads as a continuation of the form rather than a third structural zone competing with the footer plinth. It stays visible regardless of scroll position. Also raises the destructive fill of the boxed variant in dark mode, where 5% of #d96a6a over the card background was effectively invisible.

    • @getmunin/types@5.2.2
    • @getmunin/ui@5.2.2

Published packages

  • @getmunin/analytics-tracker@5.2.2
  • @getmunin/chat-widget@5.2.2
  • @getmunin/agent-host@5.2.2
  • @getmunin/agent-runtime@5.2.2
  • @getmunin/backend-core@5.2.2
  • @getmunin/core@5.2.2
  • @getmunin/dashboard-pages@5.2.2
  • @getmunin/db@5.2.2
  • @getmunin/docs-pages@5.2.2
  • @getmunin/emails@5.2.2
  • @getmunin/inspector-app@5.2.2
  • @getmunin/mcp-toolkit@5.2.2
  • @getmunin/sdk@5.2.2
  • @getmunin/types@5.2.2
  • @getmunin/ui@5.2.2