zeroclaw-labs/zeroclaw · error · anyhow::Error
Destination {} is not in allowed list
Error message
Destination {} is not in allowed list What it means
ClawdTalkChannel::initiate_call refuses to dial a destination that does not pass the channel's allowed_destinations check before any Telnyx request is made. An empty list means allow-all; otherwise a destination passes only on exact match, prefix match (starts_with, e.g. "+1555"), or the wildcard "*". This is a deliberate toll-fraud guard, so the error means local policy, not Telnyx, rejected the call. It surfaces through Channel::send because send() passes message.recipient straight into initiate_call.
Source
Thrown at crates/zeroclaw-channels/src/clawdtalk.rs:66
/// Check if a destination is allowed
fn is_destination_allowed(&self, destination: &str) -> bool {
if self.allowed_destinations.is_empty() {
return true;
}
self.allowed_destinations.iter().any(|pattern| {
pattern == "*" || destination.starts_with(pattern) || pattern == destination
})
}
/// Initiate an outbound call via Telnyx
pub async fn initiate_call(
&self,
to: &str,
_prompt: Option<&str>,
) -> anyhow::Result<CallSession> {
if !self.is_destination_allowed(to) {
anyhow::bail!("Destination {} is not in allowed list", to);
}
let request = CallRequest {
connection_id: self.connection_id.clone(),
to: to.to_string(),
from: self.from_number.clone(),
answering_machine_detection: Some(AnsweringMachineDetection {
mode: "premium".to_string(),
}),
webhook_url: None,
// AI voice settings via Telnyx Call Control
command_id: None,
};
let response = self
.client
.post(format!("{}/calls", Self::TELNYX_API_URL))
.header("Authorization", format!("Bearer {}", self.api_key))View on GitHub (pinned to 88bb9c8533)
Solutions
- Add the destination or its E.164 prefix (e.g. "+1617") to allowed_destinations under [channels.clawdtalk.<alias>]
- Normalize both allowlist entries and message.recipient to canonical E.164 (+countrycode, no spaces/dashes) so starts_with behaves
- Use "*" or an empty list only in sandbox environments — both mean allow-all
- If the number is genuinely unauthorized, treat the bail as correct and audit who requested the call
Example fix
# before [channels.clawdtalk.default] allowed_destinations = ["+1555"] # after — permit the number's prefix explicitly [channels.clawdtalk.default] allowed_destinations = ["+1555", "+1617"]
Defensive patterns
Strategy: validation
Validate before calling
// Mirror of the channel's own check (is_destination_allowed is private):
fn destination_allowed(allowed: &[String], dest: &str) -> bool {
allowed.is_empty()
|| allowed
.iter()
.any(|p| p == "*" || dest.starts_with(p) || p == dest)
}
if !destination_allowed(&allowed_destinations, &msg.recipient) {
// fix config or skip: initiate_call will bail with this exact error
} Try / catch
match channel.send(&msg).await {
Err(e) if e.to_string().contains("not in allowed list") => {
// policy rejection — never retry the same destination
}
r => r?,
} Prevention
- Keep allowed_destinations and recipients in the same E.164 format
- Treat this error as non-retryable — the same number always fails again
- Unit-test the prefix list (exact/prefix/wildcard/empty) whenever it changes
When it happens
Trigger: Calling initiate_call("+14449876543") while allowed_destinations = ["+1555"] (prefix mismatch); a SendMessage whose recipient shares no prefix with any allowlist entry; entries or recipients formatted differently ("+1 555 987 6543" vs "+1555") so starts_with fails; allowlist edited to a new country prefix while old numbers still in use.
Common situations: allow_destinations scoped to US +1 numbers while the agent tries an international destination; config migration normalizing one side but not the other; developer assumes substring matching but the code only does prefix/exact/wildcard; post-incident lockdown rejecting numbers the demo used.
Related errors
- Failed to initiate call: {}
- Failed to speak: {}
- Failed to start AI conversation: {}
- Edge TTS binary_path must be one of {:?}, got: {raw_path}
- Telnyx call failed: {body}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/41631d34e8765485.
Report an issue: GitHub.