Common Issues

Solutions to problems you might encounter when using the Labs API.

Authentication Issues

”Invalid or missing API key”

Cause: API key is incorrect or not included properly. Solutions:
  1. Check that you’re using Bearer prefix:
    headers = {"Authorization": f"Bearer {api_key}"}  # Correct
    headers = {"Authorization": api_key}  # Wrong
    
  2. Verify the key hasn’t been revoked in the Labs Portal
  3. Ensure no extra whitespace in the key

”No active subscription for collection”

Cause: Your organization doesn’t have access to this collection. Solutions:
  1. Check your subscriptions in the Labs Portal dashboard
  2. Request access to the collection via the Portal
  3. Verify you’re using the correct collection_slug

Rate Limiting

”Rate limit exceeded” (429)

Cause: Too many requests in the time window. Solutions:
  1. Implement exponential backoff:
    import time
    import urllib.error
    
    def request_with_backoff(fn, max_retries=5):
        for attempt in range(max_retries):
            try:
                return fn()
            except urllib.error.HTTPError as e:
                if e.code == 429:
                    wait = 2 ** attempt
                    time.sleep(wait)
                else:
                    raise
    
  2. Use batch endpoints instead of individual calls
  3. Check X-RateLimit-Remaining header and pause before hitting limit

Rate limit headers not present

Cause: Request failed before rate limit processing. Solution: Check for other errors (auth, validation) that occur before rate limiting.

Episode Issues

”Episode not found”

Cause: Invalid episode ID or episode was cleaned up. Solutions:
  1. Episodes expire after 24 hours of inactivity
  2. Verify the episode ID is correct
  3. Create a new episode if needed

”Episode already complete”

Cause: Trying to submit turns to a finished episode. Solution: Check episode_complete flag before submitting more turns:
if not result["episode_complete"]:
    result = submit_turn(episode_id, message)

Episode terminates immediately

Cause: Model made a critical error in first turn. Solutions:
  1. Check terminal_reason in the response
  2. Review your model’s output for harmful content
  3. Ensure tool calls are valid against the schema

Reward Issues

Rewards always zero

Cause: Model isn’t making meaningful progress. Solutions:
  1. Check if model is asking relevant questions
  2. Verify conversation format is correct
  3. Review scenario requirements

Unexpectedly low rewards

Cause: Model triggered penalty conditions. Common triggers:
  • Harmful or dangerous recommendations
  • Incorrect conclusions
  • Invalid tool usage
  • Off-topic responses
Debug:
# Log full episode for analysis
for turn in episode_turns:
    print(f"Turn {turn['number']}")
    print(f"  Action: {turn['action'][:100]}...")
    print(f"  Reward: {turn['reward']}")

Rewards don’t match expectations

Cause: Misunderstanding of reward calculation. Remember:
  • Rewards are per-turn, not cumulative
  • Rewards reflect this turn’s value, not future potential
  • Different scenarios have different reward scales

Request Issues

”Validation error”

Cause: Request body doesn’t match expected schema. Common fixes:
  1. Check required fields are present
  2. Verify field types match schema
  3. Ensure arrays have correct item structure
# Correct message format
messages = [{"role": "assistant", "content": "Hello"}]

# Wrong - missing required field
messages = [{"content": "Hello"}]

# Wrong - invalid role
messages = [{"role": "bot", "content": "Hello"}]

Tool call issues

Cause: Tool calls that don’t match the expected schema or are inappropriate for the scenario will affect your reward score. Tips:
  1. Check tool name matches available tools from the episode response
  2. Ensure input matches the json_schema provided
  3. Include all required fields
# Get available tools from episode response
tools = episode["tools"]
tool_schemas = {t["name"]: t.get("json_schema") for t in tools}

# Check tool structure before submitting
def check_tool_call(tool_call, schemas):
    schema = schemas.get(tool_call["name"])
    if not schema:
        print(f"Warning: Unknown tool: {tool_call['name']}")
    # Check input against schema...

Request timeout

Cause: Request took too long to process. Solutions:
  1. Increase client timeout:
    import urllib.request
    # Set timeout in urlopen call
    with urllib.request.urlopen(req, timeout=120) as response:
        data = response.read()
    
  2. For batch requests, reduce batch size
  3. Check for network issues

Integration Issues

”Module not found” errors

Cause: Missing dependencies. Solution: The examples use Python’s standard library (urllib.request, json), so no additional packages are required. If you see module errors, ensure you’re using Python 3.11+.

Async issues

Cause: Mixing sync and async code incorrectly. Solution: The standard library urllib.request is synchronous. For async HTTP, use asyncio with aiohttp or similar:
# Sync (standard library)
import urllib.request
with urllib.request.urlopen(req) as response:
    data = response.read()

# Async (requires: pip install aiohttp)
import aiohttp
async with aiohttp.ClientSession() as session:
    async with session.get(url, headers=headers) as response:
        data = await response.json()

Getting Help

If you can’t resolve an issue:
  1. Check the API Reference for correct request/response formats
  2. Review error messages — they indicate the exact problem
  3. Contact support at labs@tacitintelligence.co with:
    • Error message
    • Request details (sanitized)
    • Steps to reproduce