Algolia-Central

Bug-Log.md

Algolia Central — Bug Log

Regression reference for production bugs. If something breaks again, check here first.


2026-04-13 — RC3 Phoenix Pre-Demo Bugfix Session

BUG-001: SSE errors silently swallowed

  • Symptom: Console shows [ERROR] [ChatStream] SSE parse error Object. User sees blank response.
  • Root cause: useChatStream.ts:454 — inner try/catch caught both JSON parse errors AND backend event: error events, logged both as "SSE parse error", silently continued.
  • Fix: Separated JSON parse try/catch from event handling. Backend errors now surface user-facing message. Commit 187c4b18.
  • Files: src/hooks/chat/useChatStream.ts

BUG-002: Intermittent failures after 3-4 requests

  • Symptom: App works 3 times, fails on 4th. "SSE parse error" in console.
  • Root cause: In-memory LLM rate limiter (lib/llm/limiter.ts) set to 12/min. On Vercel serverless, in-memory state persists across warm invocations. Combined with BUG-001 swallowing the error.
  • Fix: Raised to 60/min. Redis-backed rate limiter (20/min per IP) is the real protection. Commit 187c4b18.
  • Files: lib/llm/limiter.ts

BUG-003: Vercel build failure — missing @anthropic-ai/sdk

  • Symptom: Vercel deploy fails: Could not resolve "@anthropic-ai/sdk"
  • Root cause: lib/llm/adapters/anthropic.ts imports the SDK but it was never added to package.json. Vite tree-shakes it locally but esbuild bundles all imports.
  • Fix: npm install @anthropic-ai/sdk. Commit d2a67adc.
  • Files: package.json

BUG-004: Discovery follow-up question missing (onion peeling broken)

  • Symptom: Maverick answers but doesn't ask a follow-up question. No discovery card appears.
  • Root cause: Two layers: 1. Gemini model drift — LLM stopped reliably outputting <discovery_pivot> XML tags in streamed markdown. 2. Zombie prevention safety net (stream_processor.ts:192-194) generated a fallback question but only added it to an internal variable — never enqueued it as a chunk event to the client.
  • Fix: Added controller.enqueue() for the fallback discovery question. Commit b3b51b24.
  • Files: lib/search/stream_processor.ts
  • CRITICAL: Fix didn't deploy initially because API bundles weren't rebuilt. See BUG-005.

BUG-005: Backend fixes don't deploy despite green Vercel build

  • Symptom: Vercel shows green deploy but old code runs. Backend fixes have no effect.
  • Root cause: Vercel serves pre-built api/search.mjs bundles, not TypeScript source. npm run build runs node scripts/bundle-api.mjs but the committed bundle was stale.
  • Fix: Run node scripts/bundle-api.mjs and commit rebuilt bundles with every backend change. Commit 75bc5ff7.
  • Files: api/search.mjs, api/diag.mjs, api/health.mjs
  • Prevention: ALWAYS rebuild bundles after touching lib/ or api-src/.

BUG-006: Quick-pick chips don't match discovery question

  • Symptom: Question asks "startup or enterprise?" but chips show "Developer / Product Manager / CTO".
  • Root cause: Static CHIP_OPTIONS mapped to signal categories. detectMissingSignal() used keyword matching with false positives ("natural language" matched "language" → stack). Even with better detection, static chips can't match dynamic LLM-generated questions.
  • Fix: Removed quick-pick chips entirely. Text input remains. Chips need backend-generated suggestions (TODO). Commit 739df1e4.
  • Files: src/components/chat/DiscoveryPromptCard.tsx
  • Symptom: "Context-Aware RetrievalIntelligent Fashion Solution" — words run together.
  • Root cause: InlineStreamAuditor.auditLinks() replaced stripped links with label text via substring splicing but didn't ensure spaces around replacements.
  • Fix: Added space padding when replacing link with label-only text. Commit 8185f2f2.
  • Files: lib/search/content_auditor.ts

BUG-008: Raw XML <discovery_pivot> tag visible in UI

  • Symptom: User sees <discovery_pivot signal="pain">Got it. So, in the grand scheme... as raw text.
  • Root cause: parseStreamTags in streamParsers.ts only stripped the tag when </discovery_pivot> closing tag was present. During streaming, opening tag arrives before close — raw XML visible in between.
  • Fix: Strip tag regardless of closure state. Extract question when content > 10 chars. Commit 15781358.
  • Files: src/hooks/chat/streamParsers.ts

BUG-009: 500-character query limit blocks natural language

  • Symptom: User types a multi-sentence question and gets "Query is too long (max 500 characters)".
  • Root cause: Hardcoded DDoS guard in api-src/search.ts:165. Not an Algolia best practice — NeuralSearch has no such limit. Too restrictive for conversational multi-turn use.
  • Fix: Raised to 2000 characters. Commit 5f99f851.
  • Files: api-src/search.ts

BUG-010: Specialist handshake lacks personality

  • Symptom: Elena/Bruno says "I'll take it from here" without introducing themselves or thanking Maverick.
  • Root cause: Handshake protocol instruction was generic: "Acknowledge the handover and ask the user to confirm scope."
  • Fix: Protocol now instructs specialist to: thank Maverick by name, introduce self with name/role, summarize understood need, ask for scope confirmation. Commit 19db70fd.
  • Files: lib/search/orchestrator.ts

Known Issues (Not Yet Fixed)

  • Discovery question quality: Brain's discovery_question.field sometimes doesn't match the actual question content. Brain says "role" but generates a scale question. Needs brain prompt tightening.
  • Quick-pick chips removed: Need backend-generated chip suggestions per discovery question. Brain prompt should return options: string[] alongside field and question.
  • Gemini model drift: Maverick's LLM stopped reliably outputting <discovery_pivot> tags. Zombie prevention catches it now, but the primary path (LLM following prompt instructions) needs investigation — may need prompt restructuring or model version pinning.