Skip to content

refactor(#12797): fail-fast on audio/embedding errors, drop fabricated zero/empty outputs - #12971

Merged
lalalune merged 1 commit into
developfrom
fix/12797-audio-vector-fail-fast
Jul 4, 2026
Merged

refactor(#12797): fail-fast on audio/embedding errors, drop fabricated zero/empty outputs#12971
lalalune merged 1 commit into
developfrom
fix/12797-audio-vector-fail-fast

Conversation

@lalalune

@lalalune lalalune commented Jul 4, 2026

Copy link
Copy Markdown
Member

Closes #12797

Premise

#12797 (split from #12271) asks the embeddings/TTS provider group — plugin-embeddings, plugin-elevenlabs, plugin-edge-tts — to throw or return an explicit failure instead of fabricating zero/marker vectors, fake/empty audio, or success-shaped defaults (extends #9324).

Premise partly pre-resolved: the parent sweep #12793 (commit e970e56135) already converted the fake-audio / zero-vector error paths in these three plugins — plugin-edge-tts teardown was annotated J6, plugin-embeddings was already fail-fast from #9324, and the plugin-elevenlabs streaming test suite ("propagates SDK errors instead of returning empty bytes") was added. This PR closes out the residual unannotated fallback literals and double-log-and-rethrow sludge, adds the missing failure-path tests, and annotates the justified keeps.

Inventory (fixed vs justified)

plugin-elevenlabs/src/index.ts — fixed

  • Fabricated empty-string API key (getApiKey(runtime) || "", 2 sites) → apiKey: string | undefined. Honest "absent" instead of a "" that reads as "a key is present". The real call resolves the key via getElevenLabsClientConfig (which throws when required and absent); the settings field only drives the inline test presence checks, where both "" and undefined are falsy — behavior-preserving.
  • Dead ?? "true"/"false" on the three boolean settings → removed. The 3-arg getSetting(runtime, key, fallback) overload delegates to resolveSetting(..., { defaultValue }), which always returns a string, so the coalescing operand was unreachable.
  • Double log-and-rethrowfetchSpeech / fetchTranscription caught, reduced to message, re-logged, and rethrew the same error, then the model handlers logged it again. Removed the inner-helper catches so failures propagate to the single model-slot boundary handler, which logs once and rethrows the original error (preserving stack/type). Never fabricates empty audio/text.

plugin-elevenlabs/src/index.ts — justified (annotated)

  • validateAudioUrl new URL() parse catch → // error-policy:J3 (untrusted-input sanitizing → explicit typed validation throw).
  • The two model-slot boundary handlers → // error-policy:J1 (log once at the model edge, rethrow so the runtime planner loop surfaces the failure).

plugin-embeddings/src/models/embedding.ts — justified (annotated)

  • Non-2xx error-body read .text().catch(() => "Unknown error")// error-policy:J2 (context-adding; an unreadable body must not mask the HTTP error being thrown). All real error paths already throw; the only synthetic return is the documented boot dimension-probe marker for null input — legitimate, unchanged.

plugin-edge-tts — no change

Already fail-fast; both teardown catches carry // error-policy:J6 (landed in #12793). No fabricated audio.

Verification

All commands run in the worktree against origin/develop.

Tests (real failure-path assertions, local SDK stubs):

$ bun run --cwd plugins/plugin-elevenlabs test   → 32 pass / 0 fail (was 27; +5 new)
$ bun run --cwd plugins/plugin-edge-tts   test   → 8 pass / 0 fail
$ bun run --cwd plugins/plugin-embeddings test   → 27 pass / 0 fail

New elevenlabs cases assert the throw (never a fabricated empty result) on: TTS SDK rejection, empty TTS stream body (null/undefined), STT SDK rejection, empty STT response (null/undefined). Logs confirm the J1 boundary fires and the error propagates, e.g. [ElevenLabs] TRANSCRIPTION failed: Empty response from ElevenLabs STT API.

Ratchet — no new slop, net neutral (two try/catch blocks removed):

$ node packages/scripts/error-policy-ratchet.mjs
[error-policy-ratchet] base origin/develop (13b7ae2369); 2 changed production source file(s)
[error-policy-ratchet]   plugins/plugin-elevenlabs/src/index.ts: emptyCatch 0->0, serverConsole 0->0
[error-policy-ratchet]   plugins/plugin-embeddings/src/models/embedding.ts: emptyCatch 0->0, serverConsole 0->0
[error-policy-ratchet] no new fallback-slop in touched files

Typecheck + lint (all touched plugins clean):

$ bun run --cwd plugins/plugin-elevenlabs typecheck   → clean
$ bun run --cwd plugins/plugin-embeddings typecheck    → clean
$ bun run --cwd plugins/plugin-edge-tts  typecheck     → clean
$ biome check <changed files>                          → No fixes applied

Evidence

  • Real-LLM / provider trajectories: N/A — this is a deterministic error-path code change. The added tests assert a throw / propagated failure on provider rejection and malformed provider response using local SDK stubs; no real audio hardware or live provider call is needed to prove a thrown error. The success paths (real streaming, real transcription) are unchanged from develop and remain covered by the existing suite.
  • Backend logs: the new J1 boundary log lines appear in the test output above.

🤖 Generated with Claude Code

…d zero/empty outputs

Fallback-slop sweep for the embeddings/TTS provider group (#12182 family,
extends #9324). The parent sweep #12793 already converted the fake-audio/
zero-vector error paths in these three plugins; this closes out the residual
unannotated fallback literals and double-log-and-rethrow sludge in
plugin-elevenlabs, and annotates the justified keeps.

plugin-elevenlabs:
- Stop fabricating an empty-string API key: getVoiceSettings/getTranscriptionSettings
  now report apiKey as `string | undefined` (honest "absent"), never `""`. The
  real call resolves the key via getElevenLabsClientConfig, which throws when
  required and absent; the settings field only drives the inline test presence
  checks (both `""` and `undefined` are falsy there — behavior-preserving).
- Remove dead `?? "true"/"false"` on the boolean settings: the 3-arg
  getSetting overload always returns a string, so the coalescing was unreachable.
- Collapse the double log-and-rethrow: the inner fetchSpeech/fetchTranscription
  helpers no longer catch-relog-rethrow the same error; failures propagate to the
  single model-slot boundary handler, which logs once and rethrows the original
  error (preserving stack/type), annotated J1. Never fabricates empty audio/text.
- Annotate the untrusted-URL parse catch J3.

plugin-embeddings:
- Annotate the non-2xx error-body read J2 (context-adding; a body that is itself
  unreadable must not mask the HTTP error being thrown).

plugin-edge-tts: already fail-fast (J6 teardown annotations landed in #12793);
no change.

Tests: extend the elevenlabs streaming suite with real failure-path cases —
TTS/STT SDK rejection and empty/malformed provider response (null/undefined) must
throw, never return fabricated empty audio or an empty transcript. 27→32 tests,
all green. edge-tts 8/8, embeddings 27/27 unchanged.

Closes #12797

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dd85684b-f287-49d5-995f-54e3403c9912

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/12797-audio-vector-fail-fast

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lalalune

lalalune commented Jul 4, 2026

Copy link
Copy Markdown
Member Author

Validated the deterministic failure-path cleanup against fresh develop (github-develop-fresh at 256fdfa):

  • bun run --cwd plugins/plugin-elevenlabs test passed: 32 tests / 150 assertions. The output includes the new boundary log lines for propagated TTS/STT failures.
  • bun run --cwd plugins/plugin-edge-tts test passed: 1 file / 8 tests.
  • bun run --cwd plugins/plugin-embeddings test passed: 3 files / 27 tests.
  • ERROR_POLICY_BASE_REF=github-develop-fresh node packages/scripts/error-policy-ratchet.mjs passed: no new fallback-slop in the touched production files.
  • bunx @biomejs/biome check plugins/plugin-elevenlabs/src/index.ts plugins/plugin-elevenlabs/__tests__/streaming.test.ts plugins/plugin-embeddings/src/models/embedding.ts passed.
  • git diff --check github-develop-fresh...HEAD passed.
  • bun run --cwd plugins/plugin-elevenlabs typecheck passed.
  • bun run --cwd plugins/plugin-embeddings typecheck passed.
  • bun run --cwd plugins/plugin-edge-tts typecheck passed.

Code review read: the changed ElevenLabs paths remove inner double-log/rethrow blocks, keep the model-slot boundary log, and add null/undefined provider-response assertions so failures throw instead of returning fabricated empty audio/text. Embeddings only adds the J2 annotation around non-2xx body-read context. I did not run live ElevenLabs audio/STT or a live embedding provider trajectory; this validation is limited to deterministic error-path behavior.

@lalalune
lalalune merged commit fa01f57 into develop Jul 4, 2026
20 of 37 checks passed
@lalalune
lalalune deleted the fix/12797-audio-vector-fail-fast branch July 4, 2026 05:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fallback slop embeddings and TTS providers: throw-never-fabricate sweep (#12271 split)

2 participants