Docs only — the diagnosis of Frank's live OpenWebUI toast, plus two crosslinks.
Error: Voice "narrator1" not found. Should be one of: af_heart, …, bm_fable
is not frank-tts refusing the name. That 29-name enum is the fixed voice
pack of Kokoro.js running in the browser, which OpenWebUI 0.11.4 ships in
its own front end as a TTS engine (browser-kokoro). The narrator1 reject
happens client-side, so the cloned-voice endpoint never sees the request.
Evidence (measured 2026-10-18, on the live service)
Exact OpenWebUI body, POSTed from inside the container
200, audio/mpeg, 7,629 B ({"model":"frank-tts","input":…,"voice":"narrator1","response_format":"mp3","speed":1.0})
podman logs open-webui
zeroaudio/speech requests for the failing click
Bundle forensics
voice table {af_heart:{name:"Heart",language:"en-us",gender:"Female",traits:"❤️",targetQuality:"A"}} + _validate_voice + model onnx-community/Kokoro-82M-v1.0-ONNX; engine select values "" (Default) and browser-kokoro; personal Kokoro.js dtype setting
Container env
no AUDIO_*/TTS/STT variable set
All four user.settings rows
no audio/TTS/voice key
The contrast is the instrument: a server-path failure leaves a container log
line and a frank-tts error; a browser-kokoro failure leaves neither.
Fix (a UI click, not a deploy)
Settings → Audio → TTS Engine → Default returns synthesis to the admin
config, i.e. frank-tts and the cloned voices. Choosing af_heart instead
keeps in-browser Kokoro, which cannot clone — fixed pack only, and it
downloads the ONNX model per tab.
Pages
Dankclaw/OpenWebUI.md — new Text-to-speech (frank-tts) section: the
endpoint contract (the shim resolves voice=<name> against /home/dank/voices/<name>/reference.wav; an unknown name is a 400 listing
what exists, never a silent fallback), the browser-Kokoro trap, and the
discriminating probe. See Also gains [[Frank TTS]].
Dankclaw/Frank TTS.md — troubleshooting table gains the symptom "a
consumer rejects narrator1 by listing 29 names and no request reaches the
façade".
log.md — worklog entry for the window, including the dankvoice merge
(0c7fe8b) and the plain-omp auto-load proof.
Verification
./tests/run.sh on the merged tree — reported in the PR comments.
Also merged origin/main (5fbbea2) into the branch during the window; the
only conflict was log.md, where both sides appended dated entries at the
tail — resolved by keeping upstream's entries first, then this window's.
## What changed
Docs only — the diagnosis of Frank's live OpenWebUI toast, plus two crosslinks.
`Error: Voice "narrator1" not found. Should be one of: af_heart, …, bm_fable`
is **not** frank-tts refusing the name. That 29-name enum is the fixed voice
pack of **Kokoro.js running in the browser**, which OpenWebUI 0.11.4 ships in
its own front end as a TTS engine (`browser-kokoro`). The `narrator1` reject
happens client-side, so the cloned-voice endpoint never sees the request.
## Evidence (measured 2026-10-18, on the live service)
| Instrument | Result |
|---|---|
| Admin config DB (`config` table) | `audio.tts.engine=openai`, `audio.tts.openai.api_base_url=http://host.containers.internal:7772/v1`, `audio.tts.model=frank-tts`, `audio.tts.voice=narrator1`, `split_on=punctuation` — correct |
| Exact OpenWebUI body, POSTed from **inside** the container | `200`, `audio/mpeg`, 7,629 B (`{"model":"frank-tts","input":…,"voice":"narrator1","response_format":"mp3","speed":1.0}`) |
| `podman logs open-webui` | **zero** `audio/speech` requests for the failing click |
| Bundle forensics | voice table `{af_heart:{name:"Heart",language:"en-us",gender:"Female",traits:"❤️",targetQuality:"A"}}` + `_validate_voice` + model `onnx-community/Kokoro-82M-v1.0-ONNX`; engine select values `""` (Default) and `browser-kokoro`; personal `Kokoro.js dtype` setting |
| Container env | no `AUDIO_*`/`TTS`/`STT` variable set |
| All four `user.settings` rows | no audio/TTS/voice key |
The contrast is the instrument: a server-path failure leaves a container log
line **and** a frank-tts error; a `browser-kokoro` failure leaves neither.
## Fix (a UI click, not a deploy)
Settings → Audio → **TTS Engine → Default** returns synthesis to the admin
config, i.e. frank-tts and the cloned voices. Choosing `af_heart` instead
keeps in-browser Kokoro, which cannot clone — fixed pack only, and it
downloads the ONNX model per tab.
## Pages
- `Dankclaw/OpenWebUI.md` — new *Text-to-speech (frank-tts)* section: the
endpoint contract (the shim resolves `voice=<name>` against
`/home/dank/voices/<name>/reference.wav`; an unknown name is a 400 listing
what exists, never a silent fallback), the browser-Kokoro trap, and the
discriminating probe. See Also gains `[[Frank TTS]]`.
- `Dankclaw/Frank TTS.md` — troubleshooting table gains the symptom "a
consumer rejects `narrator1` by listing 29 names and no request reaches the
façade".
- `log.md` — worklog entry for the window, including the `dankvoice` merge
(`0c7fe8b`) and the plain-`omp` auto-load proof.
## Verification
`./tests/run.sh` on the merged tree — reported in the PR comments.
Also merged `origin/main` (`5fbbea2`) into the branch during the window; the
only conflict was `log.md`, where both sides appended dated entries at the
tail — resolved by keeping upstream's entries first, then this window's.
The `Voice "narrator1" not found. Should be one of: af_heart, …, bm_fable`
toast is OpenWebUI 0.11.4's bundled Kokoro.js validator: the enum is
Kokoro's fixed 29-voice pack, not frank-tts's registry. Frank-tts answers
200 audio/mpeg for the exact OpenWebUI body from inside the container, and
the failing click leaves no `audio/speech` line in the container log — that
contrast is the instrument. Admin config DB is correct
(engine=openai, base URL :7772/v1, model frank-tts, voice narrator1); no
container env and no user row carries an audio override, so the
`browser-kokoro` choice is per-browser storage. Fix: Settings → Audio →
TTS Engine → Default.
A consumer that lists the 29-name af_*/am_*/bf_*/bm_* pack and refuses
narrator1 without a request reaching the façade is synthesizing in the
browser. Frank TTS's troubleshooting table gains that symptom; OpenWebUI's
See Also gains the service page.
dank
merged commit 100b62ba22 into main2026-10-18 20:38:50 -07:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What changed
Docs only — the diagnosis of Frank's live OpenWebUI toast, plus two crosslinks.
Error: Voice "narrator1" not found. Should be one of: af_heart, …, bm_fableis not frank-tts refusing the name. That 29-name enum is the fixed voice
pack of Kokoro.js running in the browser, which OpenWebUI 0.11.4 ships in
its own front end as a TTS engine (
browser-kokoro). Thenarrator1rejecthappens client-side, so the cloned-voice endpoint never sees the request.
Evidence (measured 2026-10-18, on the live service)
configtable)audio.tts.engine=openai,audio.tts.openai.api_base_url=http://host.containers.internal:7772/v1,audio.tts.model=frank-tts,audio.tts.voice=narrator1,split_on=punctuation— correct200,audio/mpeg, 7,629 B ({"model":"frank-tts","input":…,"voice":"narrator1","response_format":"mp3","speed":1.0})podman logs open-webuiaudio/speechrequests for the failing click{af_heart:{name:"Heart",language:"en-us",gender:"Female",traits:"❤️",targetQuality:"A"}}+_validate_voice+ modelonnx-community/Kokoro-82M-v1.0-ONNX; engine select values""(Default) andbrowser-kokoro; personalKokoro.js dtypesettingAUDIO_*/TTS/STTvariable setuser.settingsrowsThe contrast is the instrument: a server-path failure leaves a container log
line and a frank-tts error; a
browser-kokorofailure leaves neither.Fix (a UI click, not a deploy)
Settings → Audio → TTS Engine → Default returns synthesis to the admin
config, i.e. frank-tts and the cloned voices. Choosing
af_heartinsteadkeeps in-browser Kokoro, which cannot clone — fixed pack only, and it
downloads the ONNX model per tab.
Pages
Dankclaw/OpenWebUI.md— new Text-to-speech (frank-tts) section: theendpoint contract (the shim resolves
voice=<name>against/home/dank/voices/<name>/reference.wav; an unknown name is a 400 listingwhat exists, never a silent fallback), the browser-Kokoro trap, and the
discriminating probe. See Also gains
[[Frank TTS]].Dankclaw/Frank TTS.md— troubleshooting table gains the symptom "aconsumer rejects
narrator1by listing 29 names and no request reaches thefaçade".
log.md— worklog entry for the window, including thedankvoicemerge(
0c7fe8b) and the plain-ompauto-load proof.Verification
./tests/run.shon the merged tree — reported in the PR comments.Also merged
origin/main(5fbbea2) into the branch during the window; theonly conflict was
log.md, where both sides appended dated entries at thetail — resolved by keeping upstream's entries first, then this window's.