Hi i am getting this error 4c3", "pid": 35758, "jo...
# ask-ai
f
Hi i am getting this error 4c3", "pid": 35758, "job_id": "AJ_Cr5fcuswdyLW", "room_id": "RM_5k36DrhxqEUh"} 2026-02-24 102031 inspra_main/func/transfer_with_summary ERROR Failed to transfer participant user: TwirpError(code=not_found, message=twirp error unknown: unknown call, status=404) Traceback (most recent call last): File "/Users/vishallimaini/my_work/inspra-livekit-agent/elk-agent/functions/transfer_with_summary.py", line 89, in transfer_with_summary_handler await livekit_api.sip.transfer_sip_participant(transfer_request) File "/Users/vishallimaini/my_work/inspra-livekit-agent/.venv/lib/python3.13/site-packages/livekit/api/sip_service.py", line 815, in transfer_sip_participant return await self._client.request( ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...<11 lines>... ) ^ File "/Users/vishallimaini/my_work/inspra-livekit-agent/.venv/lib/python3.13/site-packages/livekit/api/twirp_client.py", line 129, in request raise TwirpError( ...<4 lines>... ) livekit.api.twirp_client.TwirpError: TwirpError(code=not_found, message=twirp error unknown: unknown call, status=404) 2026-02-24 102031 inspra_main/func/transfer_with_summary ERROR Failed to transfer participant user: TwirpError(code=not_found, message=twirp error unknown: unknown call, status=404) Traceback (most recent call last): File "/Users/vishallimaini/my_work/inspra-livekit-agent/elk-agent/functions/transfer_with_summary.py", line 89, in transfer_with_summary_handler await livekit_api.sip.transfer_sip_participant(transfer_request) File "/Users/vishallimaini/my_work/inspra-livekit-agent/.venv/lib/python3.13/site-packages/livekit/api/sip_service.py", line 815, in transfer_sip_participant return await self._client.request( ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...<11 lines>... ) ^ File "/Users/vishallimaini/my_work/inspra-livekit-agent/.venv/lib/python3.13/site-packages/livekit/api/twirp_client.py", line 129, in request raise TwirpError( ...<4 lines>... ) livekit.api.twirp_client.TwirpError: TwirpError(code=not_found, message=twirp error unknown: unknown call, status=404) Traceback (most recent call last): File "/Users/vishallimaini/my_work/inspra-livekit-agent/elk-agent/functions/transfer_with_summary.py", line 89, in transfer_with_summary_handler await livekit_api.sip.transfer_sip_participant(transfer_request) File "/Users/vishallimaini/my_work/inspra-livekit-agent/.venv/lib/python3.13/site-packages/livekit/api/sip_service.py", line 815, in transfer_sip_participant return await self._client.request( ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...<11 lines>... ) ^ File "/Users/vishallimaini/my_work/inspra-livekit-agent/.venv/lib/python3.13/site-packages/livekit/api/twirp_client.py", line 129, in request raise TwirpError( ...<4 lines>... ) livekit.api.twirp_client.TwirpError: TwirpError(code=not_found, message=twirp error unknown: unknown call, status=404) 102031.765 ERROR inspra_m…h_summary Failed to transfer participant user: TwirpError(code=not_found, message=twirp error unknown: unknown call, status=404) Traceback (most recent call last): File "/Users/vishallimaini/my_work/inspra-livekit-agent/elk-agent/functions/transfer_with_summary.py", line 89, in transfer_with_summary_handler await livekit_api.sip.transfer_sip_participant(transfer_request) File "/Users/vishallimaini/my_work/inspra-livekit-agent/.venv/lib/python3.13/site-packages/livekit/api/sip_ser… line 815, in transfer_sip_participant return await self._client.request( ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...<11 lines>... ) ^ File "/Users/vishallimaini/my_work/inspra-livekit-agent/.venv/lib/python3.13/site-packages/livekit/api/twirp_c… line 129, in request raise TwirpError( ...<4 lines>... ) livekit.api.twirp_client.TwirpError: TwirpError(code=not_found, message=twirp error unknown: unknown call, status=404) {"room": "3b9f13c3-b856-4b4a-a7e8-a699670754c3", "pid": 35758, "job_id": "AJ_Cr5fcuswdyLW", "room_id": "RM_5k36DrhxqEUh"} Traceback (most recent call last): File "/Users/vishallimaini/my_work/inspra-livekit-agent/elk-agent/functions/transfer_with_summary.py", line 89, in transfer_with_summary_handler await livekit_api.sip.transfer_sip_participant(transfer_request) File "/Users/vishallimaini/my_work/inspra-livekit-agent/.venv/lib/python3.13/site-packages/livekit/api/sip_service.py", line 815, in transfer_sip_participant return await self._client.request( ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...<11 lines>... ) ^ File "/Users/vishallimaini/my_work/inspra-livekit-agent/.venv/lib/python3.13/site-packages/livekit/api/twirp_client.py", line 129, in request raise TwirpError( ...<4 lines>... ) livekit.api.twirp_client.TwirpError: TwirpError(code=not_found, message=twirp error unknown: unknown call, status=404)
t
Thanks for reaching out, Vishalli. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I can see you're hitting a repeated error when calling `transfer_sip_participant`: TwirpError(code=not_found, message=twirp error unknown: unknown call, status=404) I’ll help you troubleshoot. That error means the LiveKit server can’t find an active SIP call (SIP leg) for the participant you’re trying to transfer. Here are the most likely causes and concrete checks you can run now. Quick checklist (start here) • Confirm the SIP participant is still connected at the moment you call
transfer_sip_participant
. If the participant has hung up, the transfer will fail with this 404. • Verify you are using the exact
room_name
and
participant_identity
that were used to create the SIP participant. Any mismatch will result in “unknown call.” • Ensure the transfer is attempted before any session cleanup, room deletion, or job end that would remove the call context. What to inspect next (step-by-step) 1. Check participant state before transfer ◦ Log or fetch the participant’s connection state immediately before calling
transfer_sip_participant
. Look for anything like a
sip.callStatus
of
hangup
(or equivalent) that shows the call already ended. 1. Confirm identifiers ◦ Print/log the
room_name
and
participant_identity
passed in your
TransferSIPParticipantRequest
and compare them to the values used when the SIP participant was created. The strings must match exactly. 1. Check timing / lifecycle ◦ Make sure the transfer is performed during the active agent job context and before any cleanup tasks run. If you create a SIP participant in one step and then later delete or close the room before transfer, the call will be gone. 1. Review SIP provider capabilities ◦ Confirm your SIP trunk/carrier supports SIP REFER (PSTN transfer) if your workflow relies on that. Carrier-side rejection won’t usually produce this exact error, but it’s worth confirming if transfers intermittently fail. 1. Collect relevant logs/traces ◦ Capture the sequence of events for a failing case: participant join, any attribute changes, hangup (if any), then the transfer attempt. These will show whether the call was still active at transfer time. If you want, provide these items and I’ll dive deeper • The exact
room_name
and
participant_identity
used for a failing attempt (obscure any sensitive tokens). • The log lines showing participant join and the immediate log lines just before the transfer call. • The snippet that builds the
TransferSIPParticipantRequest
(the fields you are populating). • Whether your SIP provider requires/refuses REFER transfers (carrier name or configuration detail). I can then point to the exact place in your flow where the call context is lost or suggest a code change to guard the transfer behind a participant-state check. Sources: SIP Lifecycle Management Agent | LiveKit Documentation | Agents telephony integration | LiveKit Documentation | Pass UUI data to Genesys Cloud during SIP transfers | LiveKit
f
roomId: "RM_HFwh82dyw97U"
t
Thanks — I see the roomId you gave: RM_HFwh82dyw97U. I’ll help narrow this down so we can find why the transfer is returning TwirpError(code=not_found, message=unknown call, status=404). A few quick clarifying questions so I can pinpoint the cause: • What is the
participant_identity
(or the SIP participant identity) you are trying to transfer in that room? Please obfuscate any sensitive tokens if needed. • At the moment you call
transfer_sip_participant
, is the SIP participant definitely still connected? Can you share the log lines (or a short excerpt) showing the participant join and the lines immediately before the transfer attempt for the failing case? • Do you create the SIP participant in that same room earlier in your flow? If so, does the `room_name`/`roomId` used to create the SIP participant exactly match RM_HFwh82dyw97U? • Does your SIP provider/carrier require or block SIP REFER transfers (PSTN transfer)? If you know the carrier or settings (e.g., Twilio with Call Transfer enabled), please mention it. While you collect that, try these quick checks which commonly resolve this 404: 1. Immediately before calling
transfer_sip_participant
, fetch or log the participant state and confirm there’s no
sip.callStatus
of
hangup
(or equivalent disconnected state). 2. Print the exact
room_name
and
participant_identity
you pass into the
TransferSIPParticipantRequest
and compare to the created SIP participant values — they must match exactly. 3. Ensure the transfer is issued before any room cleanup or job end that might remove the call context. If you paste: • the participant identity, • the small log snippet around join → transfer, • and the code that constructs the
TransferSIPParticipantRequest
(just the fields), I’ll analyze them and point to the exact place the call context is lost or give a code guard you can add to avoid the 404.
f
job_ctx = get_job_context() p_identity = "user" logger.info("Participants in room:") for p in job_ctx.room.remote_participants.values(): p_identity = p.identity summary = raw_arguments.get("summary", "") job_ctx = get_job_context() logger.info(f"Starting warm transfer with summary: {summary}") try: # Fetch SIP domain from Redis workspace config sip_domain = DEFAULT_SIP_DOMAIN redis_client = getattr(self, "redis_client", None) inspra_phone = getattr(self.attributes, "inspra_phone", None) if redis_client and inspra_phone: try: ws_json = redis_client.get(f"phoneNumber:{inspra_phone}") if ws_json: ws_config = json.loads(ws_json) sip_domain = ws_config.get("sipDomain", sip_domain) except Exception as e: logger.warning(f"Failed to fetch sipDomain from Redis: {e}") transfer_to = f"sip:{phone}@{sip_domain}" print("Transfer number", transfer_to) async with api.LiveKitAPI() as livekit_api: await self.session.say("No worries. Let me connect you with one of our team members. Just hold on a moment.") await asyncio.sleep(1.5) transfer_request = TransferSIPParticipantRequest( participant_identity=p_identity, room_name=job_ctx.room.name, transfer_to=transfer_to, headers={ "X-Transfer-Summary": summary, "X-Xfer-CLI": phone, }, play_dialtone=True, ) logger.debug(f"Transfer request: {transfer_request}") logger.info(f"Transfer summary: {summary}") # Execute the SIP transfer await livekit_api.sip.transfer_sip_participant(transfer_request) logger.info(f"Successfully transferred participant {p.identity} to {transfer_to}") except Exception as e: logger.error(f"Failed to transfer participant {p.identity}: {e}", exc_info=True) await self.session.say( "Sorry, all the specialists are busy right now, " "but we’ve noted your details and someone will call you back shortly." ) this is my code
t
Thanks — you already gave the roomId and the code; I reviewed your snippet and the error. I’ll focus on the two things that are causing the TwirpError 404 ("unknown call") in your flow and give concrete changes you can make right away. What I’m responding to • The repeated TwirpError 404 when calling
transfer_sip_participant
for room RM_HFwh82dyw97U. • The code you shared that selects a participant by iterating job_ctx.room.remote_participants and then calls the transfer. Root cause (concise) • The SIP participant identity you pass to
TransferSIPParticipantRequest
can be stale or not a SIP leg at transfer time. Your loop overwrites p_identity with every remote participant but does not confirm the participant is a SIP participant or still connected when you call transfer. If the SIP leg has already ended or the identity is wrong, LiveKit returns 404 unknown call. Immediate fixes (apply these in this order) 1) Select and validate an active SIP participant before transfer • Don’t just take the last participant. Find a participant whose kind is SIP and confirm it’s still connected immediately before the transfer. • Example pattern to use (pseudocode; adapt to your SDK objects):
Copy code
sip_participant = None
for p in job_ctx.room.remote_participants.values():
    if getattr(p, "kind", None) == ParticipantKind.PARTICIPANT_KIND_SIP:
        sip_participant = p
        break

if not sip_participant:
    logger.error("No SIP participant found in room - cannot transfer.")
    await self.session.say("I’m sorry — I can’t transfer the call right now.")
    return
# optional: check sip_participant.connection_state or sip.callStatus if available
p_identity = sip_participant.identity
2) Check presence/state right before calling transfer • Immediately before you call
await livekit_api.sip.transfer_sip_participant(...)
, re-check that the participant is still present in
job_ctx.room.remote_participants
and that their call state is not
hangup
(or disconnected). Log the current participants on failure to capture race conditions. 3) Remove or stop relying on
headers
in TransferSIPParticipantRequest • The
headers
field you pass is ignored for SIP transfers; it will not be delivered as you expect. If you need to pass transfer metadata (summary, CLI), put it into the transfer URI query parameters or use provider-specific mechanisms (e.g., Genesys UUI via URI parameters, Five9 via attributes→headers mapping). • Example: build transfer_to like
sip:123456789@domain?uui={encoded_summary}
if your trunk supports it. 4) Add robust error logging and a guarded retry (optional) • On failure, log the room participant list and their states:
Copy code
logger.error(f"Transfer failed for {p_identity}: {e}. Current participants: {[p.identity for p in job_ctx.room.remote_participants.values()]}")
• If appropriate, a short retry (100–300ms) after verifying the participant still exists can sometimes recover from small race windows. Only retry if you confirm the participant is still present. Why these changes will fix the 404 • The 404 is raised when there is no current SIP call for the participant identity and room. Selecting the correct participant type and verifying presence removes the race that produces stale identities. Removing unsupported
headers
avoids relying on functionality that isn’t used by the SIP transfer path. Extra checks to perform • Confirm your trunk/carrier supports SIP REFER or the transfer mechanism you expect (carrier-side settings can block transfers). • If you need to pass caller/summary data, confirm how your carrier expects it (URI params, UUI, attributes mapped to headers). If you want, paste these three items and I’ll review them and give the exact code edits: • The identity of the SIP participant you intend to transfer (obfuscate sensitive parts). • The log lines showing the participant join and the lines immediately before transfer. • How you build the final
transfer_to
value (so I can suggest URI parameter encoding if needed). I can then point out the exact line in your flow where the participant becomes unavailable or suggest a small code change to make the transfer call safe from race conditions. Sources: Pass UUI data to Genesys Cloud during SIP transfers | LiveKit | Agents telephony integration | LiveKit Documentation | How to do call transfers with Five9 | LiveKit | Preserve caller ID during SIP transfers with Twilio | LiveKit