I am unable to initialise turn detector with error...
# ask-ai
t
I am unable to initialise turn detector with error: `ERROR:Could not find file "languages.json". Make sure you have downloaded the model before running the agent. Use
python3 your_agent.py download-files
to download the model`
✅ 1
t
Thanks for reaching out, Aivis. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I see you’re blocked by the error saying
languages.json
is missing when initializing the turn detector. That happens when the turn-detector model files haven’t been downloaded yet. Let’s get you running. What to do 1. From the directory where your agent script lives, run the agent’s download-files command to fetch the model assets. Example commands: ◦ Python (when your file is
agent.py
):
Copy code
uv run agent.py download-files
• Node.js (if you use a script in package.json):
Copy code
pnpm run download-files
1. After the command finishes, restart your agent and re-run the code that initializes the turn detector. The
languages.json
and other model files should now be present. Troubleshooting if it still fails • Make sure you ran the command in the same directory as your agent script (where
agent.py
or
agent.js
lives). • Confirm the
turn-detector
plugin is installed (for Python:
livekit-agents[turn-detector]
if you installed with extras). • Check the command output for any network or permission errors while downloading model files. • If you’re running in a container or CI, ensure the download step is part of your build/startup so files persist into the runtime image. If you’d like, tell me: • Which agent file name you’re using (e.g.,
agent.py
or
agent.js
), • Whether you’re running locally, in a container, or in CI, and I’ll give the exact command and any extra steps tailored to your setup. Sources: LiveKit turn detector plugin | LiveKit Documentation | Improved end-of-turn model cuts Voice AI interruptions 39% | LiveKit | Server startup modes | LiveKit Documentation | Build a multilingual voice agent that automatically switches languages | Li..., with interactive elements
t
I did run
python3 agent.py download-files
from within my docker container and I see
2026-03-20 14:12:31,018:livekit.agents:INFO:Downloading files for livekit.plugins.silero
14:12:31.018 INFO … livekit.agents     Downloading files for livekit.plugins.silero
2026-03-20 14:12:31,019:livekit.agents:INFO:Finished downloading files for livekit.plugins.silero
14:12:31.019 INFO … livekit.agents     Finished downloading files for livekit.plugins.silero
however the location is still empty: ls -l ~/.cache/ total 12 drwxr-xr-x 4 root root 4096 Mar 20 13:52 pip drwxr-xr-x 1 root root 4096 Mar 20 13:52 uv
t
Thanks for the details — that’s helpful. You ran the download step inside the container and logs show the silero plugin finished downloading, but
~/.cache/
inside the container appears empty. Let’s narrow down where the files actually landed and why you don’t see them. Quick checklist and next steps (one at a time) 1. Confirm the user that ran the command ◦ Inside the container, run:
whoami
◦ The download writes to the invoking user’s home cache (
~/.cache/
). If you ran as
root
the files will be under
/root/.cache/
(which
ls -l ~/.cache/
will show only if your shell’s
~
is
/root
). 1. Show the absolute path listing ◦ Run these exact commands inside the container and paste the output: ▪︎
ls -la /root/.cache || true
▪︎
ls -la $HOME/.cache || true
▪︎
pwd
(to confirm your current working dir) ◦ This confirms whether files are in
/root/.cache
or another home directory. 1. Search for the downloaded files ◦ Run a container-wide search for
languages.json
or the plugin cache directory: ▪︎
find / -name "languages.json" -type f 2>/dev/null || true
▪︎
find / -maxdepth 4 -path "*/livekit*" -print 2>/dev/null || true
◦ This will show whether files exist somewhere unexpected. 1. Check for alternate cache path or environment variables ◦ Confirm if
XDG_CACHE_HOME
or
HOME
are set differently in your container: ▪︎
echo $XDG_CACHE_HOME
▪︎
echo $HOME
◦ If
XDG_CACHE_HOME
is set, the agent may write to
$XDG_CACHE_HOME
instead of
~/.cache
. 1. Verify container filesystem persistence / volume mounts ◦ If you expect files on the host at
~/.cache
, confirm you mounted the host directory into the container. If not mounted, files live only inside container. ◦ If you mounted a host dir to the container home, check correct mount path and permissions. 1. Confirm the plugin actually used by the turn-detector ◦ The log only mentions
silero
. The turn-detector and other plugins may download different files to different subfolders. After locating the cache root, list the plugin directories: ▪︎
ls -la $HOME/.cache/livekit* || ls -la /root/.cache/livekit* || true
If you want, run steps 1–3 and paste the outputs here and I’ll interpret them and give the exact command to fix it (e.g., re-run
download-files
with the correct user, set
XDG_CACHE_HOME
, or mount the cache as a Docker volume). If you prefer, tell me how you start the container (the
docker run
command or your Dockerfile) so I can point out the most likely mismatch (user, HOME, or volume). , with interactive elements
t
i checked that i am running as root. the files are still not found
t
Thanks — I know that’s frustrating. Since you ran as root and still don’t see the files, let’s run a few focused checks to discover where (or whether) the download wrote files and why they’re not visible. Please run these commands inside the same container where you executed
python3 agent.py download-files
and paste the outputs here: 1) Confirm current user, home, and working directory • whoami • echo $HOME • pwd 2) Show cache folders and permission info (try both root path and $HOME) • ls -la /root/.cache || true • ls -la $HOME/.cache || true 3) Search the container for the expected model files and related plugin folders • find / -type f -name "languages.json" 2>/dev/null || true • find / -type d -name "livekit_" -path "_/.cache/*" 2>/dev/null || true • find / -maxdepth 4 -path "_/silero_" -print 2>/dev/null || true 4) Check for environment vars that change cache path • echo $XDG_CACHE_HOME || true • env | grep -i cache || true 5) Re-run the download command with verbose logging to capture where files are written • python3 agent.py download-files --verbose ◦ If
--verbose
is not supported, re-run and paste the full log you get. Extra details that help debug • How do you start the container? (paste the
docker run
command or relevant Dockerfile snippets) • Are you mounting any host directories into the container (especially the home or ~/.cache)? • Do you have any non-root user switching in your Dockerfile (e.g., USER directives) or entrypoint scripts? What I’ll look for when you paste output • Exact path where the agent logs report writing files (the verbose log usually prints the target path). • Any permission, network, or filesystem errors during download. • Whether files exist somewhere unexpected (different HOME, XDG_CACHE_HOME, or under /tmp). If you prefer a quick workaround now • You can set
XDG_CACHE_HOME
explicitly to a known directory and re-run the download, for example: a. mkdir -p /tmp/livekit-cache b. export XDG_CACHE_HOME=/tmp/livekit-cache c. python3 agent.py download-files • Or mount a host directory into the container and set HOME/XDG_CACHE_HOME to point there so you can inspect files from the host. Send the outputs and I’ll point to the exact fix based on what we find. , with interactive elements
t
root@0100e4ee4e22:/app/livekit# find / -type f -name "languages.json" 2>/dev/null || true root@0100e4ee4e22:/app/livekit#
t
Thanks — I can tell this is frustrating. You ran the download inside the container as root and a container-wide search for
languages.json
returned nothing, so the files were not written where we expected. Let’s narrow down the cause and get the models in a location you can access. Quick summary of what we know • You ran:
python3 agent.py download-files
as root inside the container. • Logs showed the silero download completed, but
find / -name "languages.json"
returned nothing. Next focused checks and actions (please run these in the same container and paste outputs) 1) Re-run the download with full logging • Command: ◦ python3 agent.py download-files --verbose • If
--verbose
is not supported, run: ◦ python3 agent.py download-files • Paste the full log. I’m looking for any messages that indicate the target path where files are written or any warnings/errors. 2) Search for any new or likely cache folders • ls -la /root • ls -la /root/.cache || true • ls -la /tmp || true • find / -maxdepth 3 -type d -name ".cache" -print 2>/dev/null || true 3) Search for files by plugin or file pattern (broader) • find / -type f ( -name "silero_" -o -name "_silero_.pt" -o -name "languages.json" -o -name "_model*.pt" ) 2>/dev/null || true 4) Check Python environment / package location used to run the script • which python3 • python3 -c "import sys,site; print('sys.prefix=',sys.prefix); print('site.getsitepackages=', getattr(site,'getsitepackages',lambda: 'n/a')())" • pip show livekit-agents || true 5) Check for environment variables that change cache location • echo $XDG_CACHE_HOME || true • echo $HOME || true • env | grep -i XDG\|HOME || true If you want a quick workaround (works reliably inside containers) 1. Create a known cache dir and force XDG cache to it, then re-run: ◦ mkdir -p /tmp/livekit-cache ◦ export XDG_CACHE_HOME=/tmp/livekit-cache ◦ python3 agent.py download-files 1. Then check: ◦ ls -la /tmp/livekit-cache ◦ find /tmp/livekit-cache -type f -name "languages.json" || true Why this helps • The agent writes to the invoking user’s cache (either $HOME/.cache or $XDG_CACHE_HOME). If XDG_CACHE_HOME is unset or points somewhere unexpected, files may be written where you’re not looking. • Forcing XDG_CACHE_HOME to a known path ensures you can find the files and also makes it easy to mount that host directory into the container if you need persistence. If you prefer, paste: • The output of the re-run log (step 1), and • The outputs from steps 2–4 I’ll read those and tell you exactly whether the download succeeded and where the files landed — or give the one-line command to fix it. , with interactive elements
t
what setting determines what files should be downloaded by download-files script?
t
Thanks — I’m responding to your question about what controls which files the
download-files
script fetches. Short answer • The script downloads whatever model files each plugin that your agent imports and configures requests. In other words, the set of downloaded files is determined by the plugins used in your agent code. Each plugin that implements a
download-files()
method will fetch its own required assets when you run the command. What that means in practice • If your agent imports/instantiates the Silero VAD plugin, the Silero model files will be downloaded. • If your agent imports the turn-detector plugin (or any plugin that uses a
MultilingualModel
), the turn detector’s model files (including files like
languages.json
if implemented by that plugin) should be downloaded. • Custom plugins that implement
download-files()
will also cause their assets to be fetched. How to ensure the right files are downloaded 1. Check your agent code and confirm which plugins are imported and initialized. Only those plugins will participate in the download step. 2. Re-run the download command from the environment/user that actually runs the agent (and ensure the resulting cache location is the one the agent will read at runtime). 3. If a plugin completed without writing expected files, run the download step with verbose logging to inspect what each plugin attempted to download and where it wrote files. If you want, I can: • Look at your agent’s imports/initialization snippet and tell you which plugins will run
download-files()
. • Suggest the exact verbose command and environment variables to force cache into a known path inside the container so you can inspect files (for example, setting
XDG_CACHE_HOME
before running the download). Sources: Server startup modes | LiveKit Documentation | Silero VAD plugin | LiveKit Documentation | LiveKit turn detector plugin | LiveKit Documentation, with interactive elements
t
how do i confirm which plugins are imported and initialized. ?
t
You’re asking how to confirm which plugins your agent imports and initializes so you know what
download-files
should fetch — good question. Here are practical ways to check, plus a quick request so I can help directly. How to confirm which plugins are imported and initialized 1. Inspect the top of your agent file • Open your agent script (e.g.,
agent.py
) and look for import statements that reference LiveKit plugins, for example: ◦
from livekit.plugins import silero, turn_detector, noise_cancellation
◦ Or individual imports like
from livekit.plugins.silero import SileroVAD
• Any plugin module imported here is a candidate to run
download-files()
. 1. Look for plugin instantiation / registration • Search the file for places plugins are added to the agent or constructed, e.g.: ◦
agent.add_plugin(SileroVAD(...))
◦
turn_detector = TurnDetector(...)
◦ Any code that creates plugin objects or passes them to the agent will initialize that plugin at runtime. • If you see plugin objects created but not added to the agent, check for later registration. 1. Search for
download-files()
implementations or calls • Grep for
download-files
(or
download_files
) across the repo: ◦
grep -R "download-files" -n . || true
◦
grep -R "download_files" -n . || true
• The agent runner calls the
download-files()
method on every plugin that implements it. If a plugin has that method, it will be part of the download step when the plugin is imported/registered. 1. Add temporary runtime logging (quick and reliable) • Modify your agent startup to print which plugins are registered. Example concept (Python): ◦ After plugins are added to the agent, add:
Copy code
for p in agent.plugins:
        print("Registered plugin:", p.__class__.__module__, p.__class__.__name__)
• If the agent exposes a
plugins
list or similar, this prints exactly what will be invoked at download time. • If you don’t see a
plugins
list, add prints where you call
add_plugin(...)
or where plugin constructors run. 1. Use verbose download run to see which plugins execute • Run the download command with verbose logging: ◦
python3 agent.py download-files --verbose
• The logs typically show which plugin’s download routine is running (you saw silero earlier). That indicates the plugin was imported/initialized for the download step. What I can do for you • Paste the top ~100 lines of your
agent.py
(or the portion where you configure plugins). I’ll point out exactly which plugins will run
download-files()
and whether the turn-detector should be included. • Or, paste the full verbose log from
download-files
and I’ll read which plugins executed and whether any expected plugin (like the turn-detector) was skipped. Which would you prefer? , with interactive elements
t
appuser@9131cccb7d9f:~/livekit$ python3 agent.py download-files onnxruntime cpuid_info warning: Unknown CPU vendor. cpuinfo_vendor value: 0 2026-03-21 135941,452livekitINFOlivekit ffiserver139livekit ffi:server - initializing ffi server v0.12.44 2026-03-21 135941,453livekitINFOlivekit fficabi50livekit ffi:cabi - initializing ffi server v0.12.44 2026-03-21 135941,455livekit.agentsINFO:Downloading files for livekit.plugins.openai 135941.455 INFO … livekit.agents Downloading files for livekit.plugins.openai 2026-03-21 135941,457livekit.agentsINFO:Finished downloading files for livekit.plugins.openai 135941.457 INFO … livekit.agents Finished downloading files for livekit.plugins.openai 2026-03-21 135941,458livekit.agentsINFO:Downloading files for livekit.plugins.silero 135941.458 INFO … livekit.agents Downloading files for livekit.plugins.silero 2026-03-21 135941,458livekit.agentsINFO:Finished downloading files for livekit.plugins.silero INFO … livekit.agents Finished downloading files for livekit.plugins.silero
t
Thanks — I can see from your run log that
download-files
only executed download hooks for
livekit.plugins.openai
and
livekit.plugins.silero
. That explains why
languages.json
(a turn-detector file) wasn’t downloaded: the turn-detector plugin was not registered during the download step. What determines which files are downloaded • The
download-files
command calls each plugin’s
download-files()
method, but only for plugins that your agent imports and initializes. • If a plugin (like the turn detector) is not imported and passed into your
AgentSession
, its download routine won’t run and its model files will not be fetched. How to confirm (and fix) which plugins are active 1. Check your agent code for imports ◦ Look near the top of
agent.py
for plugin imports such as: ▪︎
from livekit.plugins.turn_detector.multilingual import MultilingualModel
▪︎
from livekit.plugins.silero import SileroVAD
(you likely have this already) 1. Check your session/plugin initialization ◦ Ensure you pass the turn detector into the session, for example:
Copy code
session = AgentSession(
         turn_detection=MultilingualModel(),
         stt=...,
         ...
     )
• If
turn_detection
is absent or commented out, the framework won’t register the turn detector plugin. 1. Confirm at runtime (quick ways) ◦ Run
python3 agent.py download-files --verbose
(or without
--verbose
if unsupported) and read the log lines. Each plugin that runs will print a “Downloading files for livekit.plugins.X” message. You should see an entry for
livekit.plugins.turn_detector
if it’s registered. ◦ Add a short print after plugin registration in your agent (if possible):
Copy code
for p in getattr(agent, "plugins", []):
         print("Registered plugin:", p.__class__.__module__, p.__class__.__name__)
This prints exactly what the agent will call during download. If the turn-detector import is missing or not registered • Add the import and initialize it as shown above, then re-run: ◦ python3 agent.py download-files • After that you should see logs for the turn-detector download and find files like
languages.json
in the cache directory. If the code already includes the turn detector but it still didn’t run • Paste the plugin-related lines from your
agent.py
(the imports and the
AgentSession
configuration). I’ll verify whether they’re correct and point out what to change. • Also paste the full
download-files
log after a re-run so I can see which plugin steps executed (that helps catch issues like conditional plugin registration). Quick tip for container environments • Ensure the user running the download is the same user that will run the agent and that the cache path is one you inspect (set
XDG_CACHE_HOME
to a known path like
/tmp/livekit-cache
before running if you’d prefer a predictable location). If you want, paste the relevant snippet of your
agent.py
now and I’ll point out exactly where to add/import
MultilingualModel
so the turn-detector files are downloaded. Sources: Server startup modes | LiveKit Documentation | Google AI and LiveKit | LiveKit Documentation | Build a multilingual voice agent that automatically switches languages | Li... | LiveKit turn detector plugin | LiveKit Documentation | Build a multilingual voice agent that automatically switches languages | Li..., with interactive elements
t
for future searchers: line f`rom livekit.plugins.turn_detector.multilingual import MultilingualModel` was not placed in the beginning of the file but this import was later in the agent class. therefore it was not downloaded . it is now solved