10,000 listeners in 30 days. AI hosts, real guests.Read the field note
Changelog

A New Way to Generate Episodes, Bulletproof Interview Recording, and a Theme Suggestions Fix That Took Seven PRs

This week brought a completely rebuilt episode generation page, rolling interview recording segments that survive disconnects, and the final fix for interview theme suggestions that had been returning placeholder content since launch.

Cover Image for A New Way to Generate Episodes, Bulletproof Interview Recording, and a Theme Suggestions Fix That Took Seven PRs

A lot of ground got covered this week. The episode generation page is now a proper multi-mode shell with an interview wizard baked in. Interview recording went from a single fragile end-of-session upload to a rolling segment pipeline that keeps saving as the conversation goes. And theme suggestions, which had been returning deterministic fallback content since the feature launched, finally generate real AI suggestions every time.

New features

Rebuilt episode generation page

The old generate page was a single panel. The new one is a mode selector that switches between AI suggestions, a custom prompt, RSS feeds, and interviews. Pick interview mode and a three-step wizard opens: review the transcript, pick which segments to include (with per-segment quality scores), then configure and generate. The right rail has a duration picker, a segments slider, an AI provider selector, and a Listener Q&A toggle. Generation progress shows in real time via Supabase Realtime, with a polling fallback so the page advances even if a Realtime event is missed.

The podcast overview page showing episode rows and the generate entry point

Rolling interview recording

Previously, interview audio was saved in one large upload at the end of the session. If the browser disconnected, refreshed, or timed out during that upload, the recording was lost. Now the browser saves rolling segments continuously throughout the call, for the subject, host, and any video track. Each segment is committed to storage and confirmed before moving on. A Modal-hosted stitching job reassembles everything into the final file. Sessions that used the old single-upload path still process correctly.

Interview camera card redesign

The camera consent screen on the guest join flow has been redesigned with a richer card: a warm gradient background, a "Recommended" indicator, copy about social clips, and three decorative clip mockups showing what the video ends up looking like. Guests who decline still join audio-only without any friction.

Clarity and HubSpot analytics

Microsoft Clarity is now wired in through the analytics package, gated on cookie consent, with sensitive routes blocked. HubSpot tracking loads on public marketing pages after marketing consent is granted, and page-view URLs are sanitized through the same allow-list the rest of analytics uses.

Improvements

Interview theme suggestions now actually work

Since theme suggestions launched, they had been silently returning deterministic fallback content instead of AI-generated ideas. The root cause took several passes to find: the original implementation used generateText and then tried to parse the free-form output as JSON against a strict Zod schema. At temperature 1, the model frequently added extra keys, generated non-UUID strings in UUID fields, or wrapped the JSON in markdown fences, causing both retry attempts to fail. The fix was switching to generateObject, which passes the schema to the provider as a tool parameter and enforces compliance at generation time. Separately, Anthropic was rejecting the schema because minItems: 2 on an array is not supported by their structured output implementation, so those constraints moved to app-side validation after the response arrives.

The suggestion cards were also redesigned as full-width vertical cards with the full title and angle visible. Guest names now have emoji, flag characters, and zero-width joiners stripped while preserving accented and CJK characters.

Podcast settings page showing the interview invite form with theme suggestions

Talent voice provider saves

Saving a talent with a Gemini voice (no ElevenLabs voice ID) was failing with a 500 because the server action required a non-empty voiceId. That validation has been relaxed for Gemini saves. The podcast host voice assignment endpoints now also correctly write voice_provider='gemini' or voice_provider='elevenlabs' when you switch between them.

Talent management page

Audio generation retry on transient failures

Modal FFmpeg API calls and ElevenLabs TTS requests now retry automatically on 502, 503, and 504 responses, and on network errors like ECONNRESET and socket hang up. Previously, a single transient 502 after fifteen minutes of TTS work would permanently fail the run. The retry wrapper uses exponential backoff capped at 10 seconds.

Inngest graceful error handling

Three active Sentry alerts were generating noise and burning Inngest retry budget. The suggestions job now skips gracefully when its podcast has been deleted, instead of throwing and retrying 13 times. The TIP profile reconcile cron now catches API 500s and continues rather than crashing the whole run. TCP abort errors from Inngest's own HTTP client no longer surface as unhandled rejections in Sentry.

Script editor dirty state

Regeneration was persisting script_last_generated using raw generated text like (deadpan). The script editor canonicalizes that same content as [deadpan] on load, so every section looked changed even after a fresh generation with no user edits. All generation paths now canonicalize script text through the same parser before saving the baseline.

Marketing site reliability

The homepage hero now renders the Mato embed directly instead of a click-to-load facade. The Calendly widget on the book-demo page initializes correctly with its required data-url attribute. Intercom boots with an explicit messenger call so the launcher actually appears. Episode cover image srcSets now use widths the Next image optimizer accepts.

Admin Launch plan override

The admin billing override screen now accepts "Launch" as a valid plan tier. The database check constraint had not been updated when the Launch plan was added to the UI, so those overrides were being rejected at the database level.

Bug fixes

Fixed interview recording segment indexes being derived from timestamps, which could produce values outside the 0-239 range the API accepts. Indexes are now bounded ordinals tracked per session.

Fixed segment manifest upsert failures not being captured in Sentry with full Supabase error context. Failures now include the Supabase error code, details, and hint for faster debugging.

Fixed the ElevenLabs signed-URL endpoint failing in production because ELEVENLABS_AGENT_ID had been copied into the environment with a trailing newline. All ElevenLabs environment variable reads now trim whitespace before use.

Fixed theme suggestion clicks triggering a new suggestions request. Clicking a suggestion to fill the topic field no longer counts as a topic change for the auto-refresh debounce.

© 2026 Mato. All rights reserved. English · Multiple languages available