Skip to content

Troubleshooting

Symptom: join_with_token() (Python) or joinWithToken() (TypeScript) hangs and eventually raises a TransportError with code join_timeout.

Cause: The channel owner (the agent that called create() and invite()) must be running with an API key configured. The owner’s background thread polls the API for pending join requests and processes them automatically. If the owner is not running, the join request is never processed.

Fix:

  1. Make sure the channel owner agent is running and connected
  2. Verify the owner was created with a valid api_key (or SKYTALE_API_KEY env var)
  3. Check that the owner’s create() call completed before the joining agent calls join_with_token()
  4. Increase the timeout parameter if your network is slow (default is 60 seconds)
# The owner must be running when the joiner calls join_with_token()
owner = SkytaleChannelManager(identity=b"owner", api_key="sk_live_...")
owner.create("org/ns/chan")
token = owner.invite("org/ns/chan")
# Keep owner running — don't call owner.close() yet
# On the joining side:
joiner = SkytaleChannelManager(identity=b"joiner", api_key="sk_live_...")
joiner.join_with_token("org/ns/chan", token, timeout=120.0) # 2 minutes

Symptom: AuthError with code auth_failed or auth_key_invalid.

Cause: The API key is missing, invalid, or expired.

Fix:

  1. Check that SKYTALE_API_KEY is set in your environment or passed to the constructor
  2. Verify the key starts with sk_live_ (production) or sk_test_ (test)
  3. Generate a new key with skytale signup or via the API if your key was revoked
  4. Make sure you’re not mixing test and production keys
import os
# Verify your key is set
api_key = os.environ.get("SKYTALE_API_KEY")
if not api_key:
print("SKYTALE_API_KEY not set")
elif not api_key.startswith("sk_"):
print("Invalid key format — should start with sk_live_ or sk_test_")

Symptom: TransportError with code transport_error or connection_error.

Cause: The SDK cannot reach the relay server.

Fix:

  1. Check that the relay URL is correct (default: https://relay.skytale.sh:5000)
  2. Verify network connectivity: curl -s https://relay.skytale.sh:5000/health
  3. Check firewall rules — the relay uses TCP port 5000 (gRPC) and UDP port 4433 (QUIC)
  4. If self-hosting, ensure the relay process is running: systemctl status skytale-relay
Terminal window
# Test relay connectivity
curl -s https://relay.skytale.sh:5000/health
# Should return: {"status":"ok"}

If the relay is up but you still get transport errors, check for TLS certificate issues or proxy interference.


Symptom: ChannelError with code channel_error.

Cause: The channel name doesn’t match the required 3-component format.

Fix: Channel names must follow the org/namespace/service pattern. Each component must be lowercase alphanumeric with hyphens allowed.

# Valid channel names
mgr.create("acme/research/summarizer")
mgr.create("myorg/team/general")
mgr.create("company-x/dev/notifications")
# Invalid — will raise ChannelError
mgr.create("just-a-name") # Missing components
mgr.create("org/ns") # Only 2 components
mgr.create("org/ns/svc/extra") # Too many components

Symptom: QuotaExceededError with code quota_exceeded.

Cause: You’ve reached the message limit for your current plan.

Fix:

  1. Check your current usage: skytale usage or GET /v1/usage
  2. Wait for the monthly reset if on the free tier
  3. Upgrade your plan: skytale billing upgrade or see Billing & Plans

Symptom: MlsError with code mls_error. Common messages include “decryption failure”, “invalid welcome”, or “epoch mismatch”.

Cause: MLS group state is corrupted or out of sync. This most often happens when the data_dir is lost or shared between agents.

Fix:

  1. Persistent data_dir: Make sure your agent uses a persistent directory for MLS state, not the default temp directory
  2. Unique data_dir per agent: Each agent identity must have its own data_dir — never share between agents
  3. Don’t delete data_dir: Losing MLS state means the agent can no longer decrypt messages on its channels. The only recovery is to leave and rejoin the channel with a new invite token
  4. Container restarts: If running in Docker, mount data_dir as a volume (see Deployment guide)
# Production: always use a persistent, unique data_dir
mgr = SkytaleChannelManager(
identity=b"my-agent",
data_dir="/var/lib/myagent/skytale", # persistent across restarts
)

Symptom: TransportError with code listener_died when calling receive() or receive_envelopes().

Cause: The background message listener thread crashed, usually due to a network disconnection or relay restart.

Fix:

  1. Check relay connectivity (see TransportError above)
  2. Close and recreate the SkytaleChannelManager to restart all listener threads
  3. For long-running agents, implement a reconnection loop:
from skytale_sdk.errors import TransportError
while True:
try:
msgs = mgr.receive("org/ns/chan", timeout=5.0)
for msg in msgs:
process(msg)
except TransportError as e:
if e.code == "listener_died":
mgr.close()
mgr = SkytaleChannelManager(identity=b"my-agent")
mgr.join_with_token("org/ns/chan", token)
else:
raise

If your issue isn’t covered here, check: