Troubleshooting

View as MarkdownOpen in Claude

Connection Issues

Cannot Establish WebSocket Connection

Symptoms: Connection fails immediately or times out

Possible Causes:

  • Invalid API key
  • Network/firewall blocking WebSocket connections
  • Incorrect WebSocket URL

Solutions:

  1. Verify API Key:

    1// Ensure Authorization header is correct
    2headers: {
    3 Authorization: `Bearer ${API_KEY}` // Not "Token" or "Key"
    4}
  2. Check WebSocket URL:

    1// Correct URL format
    2const url = new URL("wss://waves-api.smallest.ai/api/v1/pulse/get_text");
    3// Not "ws://" or "https://"
  3. Test Network Connectivity:

    $# Test WebSocket endpoint
    $curl -i -N -H "Connection: Upgrade" \
    > -H "Upgrade: websocket" \
    > -H "Sec-WebSocket-Version: 13" \
    > -H "Sec-WebSocket-Key: test" \
    > https://waves-api.smallest.ai/api/v1/pulse/get_text

Connection Drops Unexpectedly

Symptoms: Connection closes without sending end signal

Possible Causes:

  • Network instability
  • Server timeout
  • Invalid audio data

Solutions:

  1. Implement Reconnection Logic:

    1let ws;
    2let reconnectAttempts = 0;
    3
    4function connect() {
    5 ws = new WebSocket(url.toString(), { headers });
    6
    7 ws.onclose = (event) => {
    8 if (event.code !== 1000 && reconnectAttempts < 5) {
    9 setTimeout(connect, 1000 * Math.pow(2, reconnectAttempts++));
    10 }
    11 };
    12}
  2. Monitor Connection State:

    1setInterval(() => {
    2 if (ws.readyState !== WebSocket.OPEN) {
    3 console.warn("Connection not open, state:", ws.readyState);
    4 }
    5}, 5000);

Audio Encoding Problems

No Transcription Received

Symptoms: Connection established but no transcript messages

Possible Causes:

  • Incorrect audio encoding
  • Mismatched sample rate
  • Invalid audio format

Solutions:

  1. Verify Encoding Parameters:

    1// Ensure encoding matches your audio format
    2url.searchParams.append("encoding", "linear16"); // or linear32, alaw, mulaw, opus, ogg_opus
    3url.searchParams.append("sample_rate", "16000"); // Must match audio
  2. Check Audio Format:

    1import soundfile as sf
    2
    3audio, sample_rate = sf.read("audio.wav")
    4print(f"Sample rate: {sample_rate}")
    5print(f"Channels: {audio.shape}")
    6print(f"Format: {audio.dtype}")
    7# Should be: 16000 Hz, mono, int16
  3. Validate Chunk Format:

    1// Ensure chunks are binary (not base64 or text)
    2ws.send(audioChunk); // Uint8Array or ArrayBuffer
    3// Not: ws.send(JSON.stringify(audioChunk))

Poor Transcription Quality

Symptoms: Incorrect or garbled transcriptions

Possible Causes:

  • Wrong sample rate
  • Incorrect encoding
  • Audio quality issues

Solutions:

  1. Match Sample Rate:

    1// Audio must match sample_rate parameter
    2const audioContext = new AudioContext({ sampleRate: 16000 });
    3url.searchParams.append("sample_rate", "16000");
  2. Use Recommended Encoding:

    1// Use linear16 for best quality
    2url.searchParams.append("encoding", "linear16");
  3. Preprocess Audio:

    1# Normalize and clean audio before streaming
    2audio = audio / np.abs(audio).max() * 0.95 # Normalize
    3audio = audio.astype(np.int16) # Convert to int16

Response Handling Issues

Partial Transcripts Not Updating

Symptoms: Only final transcripts received, no partial updates

Possible Causes:

  • Not checking is_final field
  • Filtering out partial messages

Solutions:

  1. Handle Both Types:
    1ws.onmessage = (event) => {
    2 const message = JSON.parse(event.data);
    3
    4 if (!message.is_final) {
    5 // Show partial transcript
    6 displayPartial(message.transcript);
    7 } else {
    8 // Show final transcript
    9 displayFinal(message.full_transcript);
    10 }
    11};

Performance Issues

High Latency

Symptoms: Long delay between speaking and transcription

Possible Causes:

  • Chunk size too large
  • Streaming rate too slow
  • Network latency

Solutions:

  1. Optimize Chunk Size:

    1// Use recommended 4096 bytes
    2const chunkSize = 4096;
  2. Increase Streaming Rate:

    1// Send chunks every 50ms
    2setTimeout(sendChunk, 50); // Not 200ms or longer
  3. Check Network:

    $# Test latency to API
    $ping waves-api.smallest.ai

Memory Issues

Symptoms: Application crashes or slows down during streaming

Possible Causes:

  • Buffering too much audio
  • Not cleaning up resources

Solutions:

  1. Stream Directly:

    1// Stream chunks immediately, don't buffer entire file
    2const stream = fs.createReadStream("audio.wav", { highWaterMark: 4096 });
    3stream.on("data", (chunk) => ws.send(chunk));
  2. Clean Up Resources:

    1ws.onclose = () => {
    2 // Clean up audio resources
    3 if (audioContext) audioContext.close();
    4 if (stream) stream.destroy();
    5};

Browser-Specific Issues

CORS Errors

Symptoms: WebSocket connection blocked in browser

Solutions:

  1. Use WSS (Secure WebSocket):

    1// Always use wss:// in browsers
    2const url = new URL("wss://waves-api.smallest.ai/api/v1/pulse/get_text");
  2. Handle Authentication:

    1// Note: Browsers may not support custom headers in WebSocket
    2// Consider using query parameter for API key (if supported)
    3// Or use a proxy server for authentication

Microphone Access Denied

Symptoms: Cannot access microphone in browser

Solutions:

  1. Request Permissions:

    1navigator.mediaDevices.getUserMedia({ audio: true })
    2 .then(stream => {
    3 // Use stream
    4 })
    5 .catch(error => {
    6 console.error("Microphone access denied:", error);
    7 // Show user instructions
    8 });
  2. Handle HTTPS Requirement:

    • Microphone access requires HTTPS (or localhost)
    • Ensure your page is served over HTTPS

Debugging Tips

Enable Verbose Logging

1ws.onopen = () => console.log("✓ Connected");
2ws.onmessage = (event) => {
3 console.log("📨 Received:", JSON.parse(event.data));
4};
5ws.onerror = (error) => console.error("✗ Error:", error);
6ws.onclose = (event) => console.log("✗ Closed:", event.code, event.reason);

Validate Audio Before Sending

1function validateAudioChunk(chunk) {
2 if (!(chunk instanceof ArrayBuffer || chunk instanceof Uint8Array)) {
3 throw new Error("Audio chunk must be ArrayBuffer or Uint8Array");
4 }
5 if (chunk.byteLength === 0) {
6 throw new Error("Audio chunk cannot be empty");
7 }
8 if (chunk.byteLength > 8192) {
9 console.warn("Chunk size exceeds recommended 4096 bytes");
10 }
11 return true;
12}

Monitor Session State

1let sessionStats = {
2 chunksSent: 0,
3 messagesReceived: 0,
4 partialCount: 0,
5 finalCount: 0
6};
7
8ws.onmessage = (event) => {
9 sessionStats.messagesReceived++;
10 const message = JSON.parse(event.data);
11 if (message.is_final) {
12 sessionStats.finalCount++;
13 } else {
14 sessionStats.partialCount++;
15 }
16 console.log("Session stats:", sessionStats);
17};

Getting Help

If you continue to experience issues:

  1. Check API Status: Verify the API is operational

  2. Review Documentation: Ensure you’re following the correct API version

  3. Test with Sample Code: Use the provided examples as a baseline

  4. Note down: Reach out with:

    • Session ID (if available)
    • Error messages
    • Code snippets (sanitized of API keys)
    • Network conditions (if applicable)
  5. Reach out to us: