fix: resolve critical interview flow bug causing double Hume AI connection#497
Conversation
Add 30s staleTime to useJob and useCustomisedSystemPrompt hooks to enable instant cache hits while background refetch happens. This prevents redundant fetches when navigating between pages that use the same data.
Remove premature Hume connection on /new page that was causing the AI to connect twice (once without context, once with context). This fixes critical production bugs: - AI talking random nonsense initially - Blank page after redirect - Frozen interview timer - AI stopping mid-interview Changes: - Remove useVoice connection logic from interview-placeholder.tsx - Add React Query cache pre-population on interview creation - Move chat metadata saving to interview-controller.tsx after connection - Only connect once with full context on the interview page
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @bhekanik's task —— View job LGTM 🚢 Todo List:
Good Patterns
Recommendation🚢 SHIP IT - Solid bug fix with performance bonus. The cache strategy is particularly clever for eliminating the loading spinner experience. |
There was a problem hiding this comment.
Pull Request Overview
This PR fixes a critical production bug where the interview flow was connecting to Hume AI twice, causing the AI to speak nonsense initially followed by a blank page with a frozen timer. The solution implements a single connection point and optimizes React Query caching.
- Removed premature Hume AI connection from lobby page to prevent double connections
- Added React Query cache pre-population for instant page loads after interview creation
- Moved chat metadata saving to happen after successful connection on the interview page
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/hooks/useJob.ts | Added 30s staleTime for instant cache hits while allowing background refetch |
| src/hooks/useCustomisedSystemPrompt.tsx | Added 30s staleTime for better cache behavior |
| src/components/interview/interview-controller.tsx | Added chat metadata saving logic after Hume AI connection |
| src/components/interview-placeholder.tsx | Removed Hume connection, added cache pre-population, simplified interview creation flow |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| // Initialize with empty metadata - will be populated when connecting on interview page | ||
| chatGroupId: "", | ||
| customSessionId: "", | ||
| requestId: "", | ||
| humeChatId: "", |
There was a problem hiding this comment.
[nitpick] Consider using null or undefined instead of empty strings for optional metadata fields to better represent the absence of data and maintain consistency with the TypeScript types.
| const handleStartInterview = async () => { | ||
| // Don't connect here - just create the interview and redirect | ||
| // The interview page will handle the connection with proper context | ||
| try { | ||
| await createInterview({ |
There was a problem hiding this comment.
The function calls await createInterview() but createInterview is a mutation function that doesn't return a Promise. Use createInterviewMutation.mutateAsync() instead to properly await the operation.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
| const handleStartInterview = async () => { | ||
| // Don't connect here - just create the interview and redirect | ||
| // The interview page will handle the connection with proper context | ||
| try { | ||
| await createInterview({ | ||
| jobId: params.jobId as string, | ||
| chatGroupId: chatMetadata?.chatGroupId || "", | ||
| customSessionId: chatMetadata?.customSessionId || "", | ||
| requestId: chatMetadata?.requestId || "", | ||
| humeChatId: chatMetadata?.chatId || "", | ||
| type: interviewToBeCreated.type, | ||
| duration: interviewToBeCreated.duration, | ||
| chatGroupId: "", | ||
| humeChatId: "", | ||
| customSessionId: "", | ||
| requestId: "", |
There was a problem hiding this comment.
Creating interview without Hume IDs breaks POST /api/interviews
Starting the interview now calls createInterview with empty chatGroupId, humeChatId, customSessionId, and requestId. However, the server’s /api/interviews endpoint still validates that chatGroupId and humeChatId are provided and rejects the request when either is falsy (Missing required field: chatGroupId / humeChatId). Because no server changes accompany this client update, the mutation will always return 400 and the user can never create an interview, effectively blocking the flow.
Useful? React with 👍 / 👎.
Makes chatGroupId and humeChatId nullable in the database schema and updates API validation to allow interview creation without Hume metadata. These fields are now populated later when the Hume connection is established on the interview page. Changes: - Make chatGroupId and humeChatId nullable in database schema - Remove API validation requiring these fields on creation - Add null check in audio reconstruction Lambda - Remove duplicate key assignments in interview creation - Generate migration to alter table constraints This fixes the blocking issue where interviews could not be created because the client no longer provides Hume metadata upfront (it connects later with full context).
|
Claude finished @bhekanik's task —— View job Claude finished @bhekanik's task —— View job LGTM 🚢 Todo List:
Good Patterns
Recommendation🚢 SHIP IT - Solid bug fix with performance bonus. The cache strategy is particularly clever for eliminating the loading spinner experience. |
🔧 Critical Fix AppliedThe bot correctly identified a blocking P0 issue - the client was trying to create interviews without Hume metadata, but the server still required those fields. Problem
Solution (commit 022ee4a)Made Hume metadata fields optional during creation:
Flow Now WorksTesting
The PR is now unblocked and ready for review! |
🗄️ Database Migration Check✅ Migration dry-run successful Migration Files Found: 10
...and 5 more These migrations will be applied automatically when merged to main. |
Summary
Fixes a critical production bug where the interview flow was connecting to Hume AI twice, causing AI to speak random nonsense initially, followed by a blank page with a frozen timer.
Problem
The interview creation flow had a race condition:
Solution
1. Single Connection Point
2. React Query Cache Pre-population
3. Optimized Cache Behavior
staleTimeto queries for instant cache hitsChanges Made
Performance Optimization
useJobanduseCustomisedSystemPromptCritical Bug Fix
/newpageFiles Changed:
src/components/interview-placeholder.tsx- Removed Hume connection, added cache pre-populationsrc/components/interview/interview-controller.tsx- Added chat metadata saving after connectionsrc/hooks/useCustomisedSystemPrompt.tsx- Added staleTime for better cache behaviorsrc/hooks/useJob.ts- Added staleTime for better cache behaviorTesting
Impact
Before:
After:
Type of Change
Checklist
Related Issues
Fixes critical production issue affecting interview start flow.