MeshChatX version
4.9.1
Release channel
Stable
Platform
Headless server (Docker / pip / uv)
Operating system
Linux
OS details (if Other)
Debian 13, x86_64, no PulseAudio or PipeWire
How did you install MeshChatX?
pip / uv / PyPI
What happened?
On a host with no audio server, MeshChatX installs its hostless backends and
logs WebAudioBridge: installed hostless LXST audio backends (no PulseAudio).
Voice calls then fail in four separate places. Each fault hides the next, so
they only appear one at a time, in this order. Tested on 4.9.1 with LXST 0.5.3
and RNS 1.5.4, with a Sideband client calling in.
1. Incoming calls never ring. HostlessAudioSink
(src/backend/web_audio_bridge.py) writes its own __init__ and subclasses
LocalSink, which in LXST is an empty class, so it never gets the attributes
LineSink.__init__ sets. LXST's Telephony.__update_output_buffer_targets
reads and writes buffer_max_height, autostart_min, streaming and calls
wait_for_frames(). The first incoming call raises inside the
remote-identified callback and the call dies before ringing.
2. Saved voicemails raise no notification.
voicemail_manager.stop_recording calls
on_new_voicemail_callback(hash, name, duration) with three arguments.
identity_context.setup assigns lambda vm: self.app.on_new_voicemail_received(vm, context=self),
which takes one — while the app's own handler is
on_new_voicemail_received(remote_hash, remote_name, duration, context=None).
The recording is written first, so the audio survives, but the notification is
lost and the failure is logged as "Error stopping recording".
3. The voicemail greeting is inaudible. voicemail_manager builds
OpusFileSource(greeting_path, target_frame_ms=60), and LXST's timed
argument defaults to False, so an 8-second greeting is pushed into the
transmit mixer as fast as the mixer will accept it. The trailing partial frame
(1,325 samples, 27.6 ms) is not a legal Opus frame duration and the mixer
rejects it. Passing timed=True makes the greeting play in real time.
4. The receive path dies mid-call. Tee
(src/backend/telephone_manager.py) is declared as a plain class, so
Pipeline.__init__'s issubclass(type(sink), Sink) check rejects it, and
because it is also assigned to telephone.audio_output, teardown raises
'Tee' object has no attribute 'stop' while processing incoming packets.
Upstream, not yours, but it surfaces here: LXST's LinkSource defines no
samplerate, and LXST/Sinks.py reads source.samplerate on the first frame
it accepts, so every incoming call packet raises AttributeError and
voicemail recordings come out as digital silence (measured: peak amplitude
0.0003 across four recordings, against 0.49 after patching). LXST has issues
disabled on GitHub, so I am flagging it where it shows up.
What did you expect?
A call from an LXST client to a headless MeshChatX should ring, play the
greeting audibly, record the caller, and notify.
Steps to reproduce
- Install MeshChatX 4.9.1 from PyPI on a Linux host with no PulseAudio or
PipeWire. Run headless with --no-https --host 0.0.0.0 --port 8001.
- Enable voicemail and telephone announce, and record a greeting.
- Call it from another LXST client (Sideband 2.1.0 here) over a Reticulum TCP
link.
- Watch the service log. Each fault above appears in turn once the previous
one is worked around.
Logs or error output
[Error] Error while executing remote identified callback from <…>. The contained exception
was: 'HostlessAudioSink' object has no attribute 'buffer_max_height'
[Error] Error stopping recording: IdentityContext.setup.<locals>.<lambda>() takes 1
positional argument but 3 were given
[Error] Error while mixing frame on <LXST.Mixer.Mixer object>: The effective frame
duration (27.6 ms) was not one of the acceptable values.
[Error] WebAudioBridge: failed to tee receive path: Audio pipeline initialised with
invalid sink
[Error] <lxst.telephony/…> could not process incoming packet: 'Tee' object has no
attribute 'stop'
[Error] <LXST.Network.LinkSource object> could not process incoming packet:
'LinkSource' object has no attribute 'samplerate'
All four MeshChatX faults are patched locally and voice now works end to end
(call connects, greeting plays, caller is recorded at a normal level). Happy to
open a PR if the shapes below look right:
- `HostlessAudioSink`: set `buffer_max_height = 3`, `autostart_min = 1`,
`streaming = False` and add a no-op `wait_for_frames()`.
- `identity_context`: `lambda remote_hash, remote_name, duration: self.app.on_new_voicemail_received(remote_hash, remote_name, duration, context=self)`.
- `voicemail_manager`: `OpusFileSource(greeting_path, target_frame_ms=60, timed=True)`.
- `Tee`: subclass `LXST.Sinks.Sink`, forward `start`/`stop`/`release` to its
sinks, and carry the same buffer attributes as the hostless sink.
Checklist
MeshChatX version
4.9.1
Release channel
Stable
Platform
Headless server (Docker / pip / uv)
Operating system
Linux
OS details (if Other)
Debian 13, x86_64, no PulseAudio or PipeWire
How did you install MeshChatX?
pip / uv / PyPI
What happened?
On a host with no audio server, MeshChatX installs its hostless backends and
logs
WebAudioBridge: installed hostless LXST audio backends (no PulseAudio).Voice calls then fail in four separate places. Each fault hides the next, so
they only appear one at a time, in this order. Tested on 4.9.1 with LXST 0.5.3
and RNS 1.5.4, with a Sideband client calling in.
1. Incoming calls never ring.
HostlessAudioSink(
src/backend/web_audio_bridge.py) writes its own__init__and subclassesLocalSink, which in LXST is an empty class, so it never gets the attributesLineSink.__init__sets. LXST'sTelephony.__update_output_buffer_targetsreads and writes
buffer_max_height,autostart_min,streamingand callswait_for_frames(). The first incoming call raises inside theremote-identified callback and the call dies before ringing.
2. Saved voicemails raise no notification.
voicemail_manager.stop_recordingcallson_new_voicemail_callback(hash, name, duration)with three arguments.identity_context.setupassignslambda vm: self.app.on_new_voicemail_received(vm, context=self),which takes one — while the app's own handler is
on_new_voicemail_received(remote_hash, remote_name, duration, context=None).The recording is written first, so the audio survives, but the notification is
lost and the failure is logged as "Error stopping recording".
3. The voicemail greeting is inaudible.
voicemail_managerbuildsOpusFileSource(greeting_path, target_frame_ms=60), and LXST'stimedargument defaults to
False, so an 8-second greeting is pushed into thetransmit mixer as fast as the mixer will accept it. The trailing partial frame
(1,325 samples, 27.6 ms) is not a legal Opus frame duration and the mixer
rejects it. Passing
timed=Truemakes the greeting play in real time.4. The receive path dies mid-call.
Tee(
src/backend/telephone_manager.py) is declared as a plain class, soPipeline.__init__'sissubclass(type(sink), Sink)check rejects it, andbecause it is also assigned to
telephone.audio_output, teardown raises'Tee' object has no attribute 'stop'while processing incoming packets.Upstream, not yours, but it surfaces here: LXST's
LinkSourcedefines nosamplerate, andLXST/Sinks.pyreadssource.samplerateon the first frameit accepts, so every incoming call packet raises
AttributeErrorandvoicemail recordings come out as digital silence (measured: peak amplitude
0.0003 across four recordings, against 0.49 after patching). LXST has issues
disabled on GitHub, so I am flagging it where it shows up.
What did you expect?
A call from an LXST client to a headless MeshChatX should ring, play the
greeting audibly, record the caller, and notify.
Steps to reproduce
PipeWire. Run headless with
--no-https --host 0.0.0.0 --port 8001.link.
one is worked around.
Logs or error output
Checklist