chatwoot/chatwoot · error · ArgumentError
Business management token is only supported for WhatsApp Emb
Error message
Business management token is only supported for WhatsApp Embedded Signup inboxes
What it means
Whatsapp::BusinessManagementTokenService#validate_channel! raises ArgumentError unless the channel is a WhatsApp Cloud channel created through Embedded Signup — specifically provider == 'whatsapp_cloud' AND provider_config['source'] == 'embedded_signup'. Channels created manually (API/CLI), via other WhatsApp providers, or without the embedded_signup marker fail the second check after the Chatwoot Cloud check passes.
Source
Thrown at app/services/whatsapp/business_management_token_service.rb:25
validate_channel!
raise ArgumentError, 'Business management token is required' if business_management_token.blank?
Whatsapp::BusinessManagementTokenValidationService.new(
business_management_token,
@channel.provider_config['business_account_id']
).perform
@channel.business_management_token = business_management_token
@channel.save!(validate: false)
end
private
def validate_channel!
raise ArgumentError, 'Business management token is only available on Chatwoot Cloud' unless ChatwootApp.chatwoot_cloud?
return if @channel.provider == 'whatsapp_cloud' && @channel.provider_config['source'] == 'embedded_signup'
raise ArgumentError, 'Business management token is only supported for WhatsApp Embedded Signup inboxes'
end
end
View on GitHub (pinned to ed230f9bc0)
Solutions
- Use a WhatsApp Cloud channel created via the embedded signup flow, then call the service on it.
- If the channel is legitimately embedded-signup but misconfigured, set provider_config['source'] = 'embedded_signup' on the channel.
- For manually created channels, manage the access token in the channel's own provider config instead of this service.
Example fix
# before (manually created channel)
channel.update!(provider: 'whatsapp_cloud', provider_config: { 'source' => 'api' })
Whatsapp::BusinessManagementTokenService.new(channel).update!(token) # raises
# after
channel.update!(provider_config: { 'source' => 'embedded_signup', 'business_account_id' => '123' })
Whatsapp::BusinessManagementTokenService.new(channel).update!(token) Defensive patterns
Strategy: validation
Validate before calling
eligible = channel.provider == 'whatsapp_cloud' && channel.provider_config['source'] == 'embedded_signup'
render_error('Token only supported for WhatsApp Embedded Signup inboxes') && next unless eligible
Whatsapp::BusinessManagementTokenService.new(channel).update!(token) Type guard
def embedded_signup_whatsapp_channel?(channel) channel.provider == 'whatsapp_cloud' && channel.provider_config['source'] == 'embedded_signup' end
Prevention
- Only surface the token settings for channels flagged provider_config['source'] == 'embedded_signup'.
- Preserve the source marker when migrating or cloning WhatsApp channels.
- For manually created channels, configure tokens in provider settings instead.
When it happens
Trigger: Calling update! with a 360dialog or WhatsApp Cloud channel created by hand (provider_config['source'] nil or 'api'), or a non-WhatsApp channel entirely.
Common situations: Admin tries to attach a business token to a manually created WhatsApp inbox; channel was migrated/cloned and lost provider_config['source']; provider_config hash missing entirely.
Related errors
- WhatsApp App ID is required
- WhatsApp Configuration ID is required
- Business management token is required
- Missing sdp_offer for accept — call may have ended.
- Channel already exists for this phone number: %{phone_number
AI-assisted analysis of chatwoot/chatwoot@ed230f9bc0 (2026-08-21).
Data as JSON: /api/errors/5e85fc17f5ba22db.
Report an issue: GitHub.