```python
from azure.identity import DefaultAzureCredential
from azure.servicebus import ServiceBusClient, ServiceBusMessage

credential = DefaultAzureCredential()
client = ServiceBusClient(
    fully_qualified_namespace="YOUR-NAMESPACE.servicebus.windows.net",
    credential=credential,
)
sender = client.get_queue_sender(queue_name="[queue]")
with sender, client:
    sender.send_messages(ServiceBusMessage("hello"))
```

Traps:

- **Wrong role, again.** The data role is "Azure Service Bus Data Owner" (or Receiver/Sender for narrower scope). Namespace Contributor lets you manage the namespace but not send a single message.
- **fully_qualified_namespace, not the connection string.** The param wants `[namespace].servicebus.windows.net` with no scheme, no keys. Passing a connection string here is the most common TypeError-adjacent mistake.
- **Sender/receiver lifecycle.** Senders and receivers hold AMQP links. Create them per unit of work or keep one long-lived; do not create one per message in a loop.
- **Peek vs receive.** `receive_messages()` locks the message; you must `complete_message()` or it reappears after the lock timeout. For just looking, use the receiver in PEEK_LOCK mode carefully or `peek_messages()`.
- **Sessions.** If the queue has sessions enabled, `get_queue_receiver(..., session_id="[id]")` is required; without it every receive errors.

Verify: send one message, receive it with a short max_wait_time, complete it, then confirm the queue's active message count is back to baseline in the portal.