{"record":{"id":"635177e02fabf409","repo":"chatwoot/chatwoot","slug":"failed-to-initiate-call","errorCode":null,"errorMessage":"Failed to initiate call","messagePattern":"Failed to initiate call","errorType":"exception","errorClass":"Voice::CallErrors::CallFailed","httpStatus":422,"severity":"error","filePath":"enterprise/app/services/enterprise/whatsapp/providers/whatsapp_cloud_service.rb","lineNumber":111,"sourceCode":"  def initiate_call_body(to_phone_number, sdp_offer)\n    {\n      messaging_product: 'whatsapp', to: to_phone_number, action: 'connect',\n      session: { sdp: sdp_offer, sdp_type: 'offer' }\n    }.to_json\n  end\n\n  def process_initiate_call_response(response)\n    return response.parsed_response if response.success?\n\n    Rails.logger.error \"[WHATSAPP CALL] initiate_call failed: status=#{response.code} body=#{response.body}\"\n    parsed = response.parsed_response.is_a?(Hash) ? response.parsed_response : {}\n    error = parsed['error'].is_a?(Hash) ? parsed['error'] : {}\n    error_code = error['code']\n    error_msg = meta_error_message(error, 'Failed to initiate call')\n\n    raise Voice::CallErrors::NoCallPermission, error_msg if error_code == Voice::CallErrors::NO_CALL_PERMISSION_CODE\n\n    raise Voice::CallErrors::CallFailed, error_msg\n  end\n\n  # Meta often returns a blank error_user_msg (e.g. code 131044 business-eligibility);\n  # an empty string is truthy, so `||` would surface it. Prefer the first non-blank field.\n  def meta_error_message(error, default)\n    error['error_user_msg'].presence || error['message'].presence || error['error_user_title'].presence || default\n  end\nend\n","sourceCodeStart":93,"sourceCodeEnd":120,"githubUrl":"https://github.com/chatwoot/chatwoot/blob/ed230f9bc068e7a13dd5c0404d5465a204b68d4c/enterprise/app/services/enterprise/whatsapp/providers/whatsapp_cloud_service.rb#L93-L120","documentation":"After initiate_call, the WhatsApp Cloud provider inspects a non-success response: if Meta's error code equals Voice::CallErrors::NO_CALL_PERMISSION_CODE (138006) it raises Voice::CallErrors::NoCallPermission, otherwise Voice::CallErrors::CallFailed, with the first non-blank of error_user_msg / message / error_user_title or the fallback 'Failed to initiate call'. The status and body are logged as [WHATSAPP CALL] for diagnosis.","triggerScenarios":"WhatsApp voice call initiation where the Cloud API returns non-2xx: WABA/number lacks Cloud Calling eligibility (e.g. code 131044 with a blank error_user_msg, which is why presence-aware selection is used), an invalid/expired access token, or a Meta 5xx.","commonSituations":"New WhatsApp Business Account without voice access; contact has not granted call permission (138006); rotated or expired permanent token; Meta platform incident.","solutions":["Confirm WhatsApp Cloud Calling is enabled/eligible for the phone number in Meta Business Manager","For NoCallPermission (code 138006), have the contact accept WhatsApp call permissions, then retry","Verify the channel's access token is valid and has calling permissions; re-issue if rotated","Read the [WHATSAPP CALL] log line (status + body) and check Meta system status for outages"],"exampleFix":"# before\nprovider_service.initiate_call(call.provider_call_id, sdp_offer)\n# raises Voice::CallErrors::CallFailed: Failed to initiate call\n\n# after\nbegin\n  provider_service.initiate_call(call.provider_call_id, sdp_offer)\nrescue Voice::CallErrors::NoCallPermission\n  # surface 'contact has not granted call permission' in UI, do not retry immediately\nrescue Voice::CallErrors::CallFailed => e\n  Rails.logger.error(\"initiate_call hard failure: #{e.message}\")\nend","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"begin\n  provider_service.initiate_call(call_id, sdp_offer)\nrescue Voice::CallErrors::NoCallPermission\n  # 138006: contact must grant call permission — surface instruction, do not auto-retry\nrescue Voice::CallErrors::CallFailed => e\n  # eligibility/token/Meta failure — log e.message (already prefers error_user_msg) and alert\nend","preventionTips":["Verify WhatsApp Cloud Calling eligibility for the number before enabling voice","Keep the channel access token fresh and monitor expiry","Distinguish NoCallPermission (user action needed) from CallFailed (config/Meta issue) in handling","Watch the [WHATSAPP CALL] log lines for the raw status/body"],"tags":["whatsapp","voice","meta-api","third-party-api","enterprise","webrtc"],"backgroundTag":"whatsapp-api-error","analyzedSha":"ed230f9bc068e7a13dd5c0404d5465a204b68d4c","analyzedAt":"2026-08-21T12:45:25.920Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}