Error Troubleshooting

Error Troubleshooting Guide

Comprehensive guide to diagnosing and fixing common errors in TELA development and deployment.

🔧

Quick Debug: Most issues fall into 5 categories: XSWD connection, file size, deployment errors, runtime errors, and network issues.

Table of Contents


App Not Rendering (Shows File Listing)

🚨

Most Common Deployment Mistake: Your main HTML file is not named index.html

Symptoms

When you navigate to your deployed TELA app in Hologram or any TELA browser, instead of seeing your application, you see:

Snake_Deluxe.html

or

myapp.html
gaza.html
main.html

The browser shows a file listing with a clickable link instead of rendering your app.

Cause

TELA browsers look for index.html as the default entry point. If your DOC1 file has any other name, the browser doesn't know which file to render automatically, so it displays a file listing instead.

This is NOT a bug - it's how web servers work. Just like Apache or Nginx serve index.html by default, TELA browsers do the same.

Solution

Before deploying, rename your main HTML file to index.html:

# ❌ Wrong - will show file listing
my-app/
├── Snake_Deluxe.html   Named incorrectly
├── style.css
└── app.js
 
# ✅ Correct - will render properly
my-app/
├── index.html   Renamed correctly
├── style.css
└── app.js

If Already Deployed

If you've already deployed with the wrong filename, you have two options:

Option 1: Redeploy with correct filename (Recommended)

  1. Rename your file to index.html
  2. Deploy as a new DOC: tela-cli install-doc
  3. Update your INDEX to point to the new DOC SCID

Option 2: Create a redirect index.html (Workaround) Create a new index.html that redirects to your existing file:

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="refresh" content="0; url=Snake_Deluxe.html">
  <title>Redirecting...</title>
</head>
<body>
  <p>Redirecting to <a href="Snake_Deluxe.html">Snake_Deluxe.html</a>...</p>
</body>
</html>

Deploy this index.html as DOC1, and keep your original file as DOC2.

Prevention Checklist

Before every TELA deployment:

  • Main HTML file is named index.html
  • index.html is deployed as DOC1 (first document)
  • All other files (CSS, JS, images) are referenced correctly from index.html
💡

Pro Tip: Create a deployment checklist and always verify your entry point filename before running tela-cli install-index.


XSWD Connection Errors

Error: "Invalid name" or "Invalid description"

Symptoms:

{
  "accepted": false,
  "message": "Could not connect the application: Invalid name"
}

or

{
  "accepted": false,
  "message": "Could not connect the application: Invalid description"
}

Common Causes:

  1. Unicode characters in name or description (most common!)
  2. Empty name or description
  3. Name or description exceeds 255 characters
🚨

ASCII Only: The XSWD server strictly validates that name and description contain only ASCII characters (bytes 0-127). Unicode characters like smart quotes, emojis, or non-English characters will cause silent rejection.

Diagnosis:

// Check for non-ASCII characters
function hasNonASCII(str) {
    for (let i = 0; i < str.length; i++) {
        if (str.charCodeAt(i) > 127) {
            console.error(`Non-ASCII at position ${i}: "${str[i]}" (code: ${str.charCodeAt(i)})`);
            return true;
        }
    }
    return false;
}
 
// Test your app data
const appData = {
    name: "My App",
    description: "View transactions"  // Smart quote - INVALID!
};
 
hasNonASCII(appData.name);        // Check name
hasNonASCII(appData.description); // Check description

Common Unicode Culprits:

CharacterCodeReplacement
" " (smart quotes)8220, 8221" (straight quote)
' ' (smart apostrophes)8216, 8217' (straight apostrophe)
(em dash)8212-- or -
(en dash)8211-
(ellipsis)8230...
(bullet)8226* or -
EmojisVariousRemove or use text

Solution:

// Sanitize strings to ASCII only
function toASCII(str) {
    return str
        .replace(/[\u2018\u2019]/g, "'")   // Smart quotes to straight
        .replace(/[\u201C\u201D]/g, '"')   // Smart double quotes
        .replace(/\u2014/g, '--')          // Em dash
        .replace(/\u2013/g, '-')           // En dash
        .replace(/\u2026/g, '...')         // Ellipsis
        .replace(/[^\x00-\x7F]/g, '');     // Remove remaining non-ASCII
}
 
const applicationData = {
    "id": await generateAppId("My App"),
    "name": toASCII("My App"),
    "description": toASCII("View blockchain data - read only"),
    "url": window.location.origin
};

Error: "Invalid ID size" or "Invalid hexadecimal ID"

Symptoms:

{
  "accepted": false,
  "message": "Could not connect the application: Invalid ID size"
}

Cause: The id field must be exactly 64 hexadecimal characters.

Solution:

// Option 1: Random generation (store for reuse)
const appId = Array.from({length: 64}, () => 
    Math.floor(Math.random() * 16).toString(16)
).join('');
localStorage.setItem('xswd_app_id', appId);
 
// Option 2: SHA-256 of app name (deterministic)
async function generateAppId(appName) {
    const data = new TextEncoder().encode(appName);
    const hash = await crypto.subtle.digest('SHA-256', data);
    return Array.from(new Uint8Array(hash))
        .map(b => b.toString(16).padStart(2, '0')).join('');
}
 
// Option 3: Static/hardcoded
const appId = "71605a32e3b0c44298fc1c549afbf4c8496fb92427ae41e4649b934ca495991b";
 
// Verify length
console.log(appId.length);  // Must be 64

Error: "Invalid URL compared to origin"

Symptoms:

{
  "accepted": false,
  "message": "Could not connect the application: Invalid URL compared to origin"
}

Cause: The url field doesn't match the HTTP Origin header sent by the browser.

Solution:

// Always use the actual origin
const applicationData = {
    "id": appId,
    "name": "My App",
    "description": "My application",
    "url": window.location.origin  // Correct: uses actual origin
    // NOT: "http://localhost:8080"  // Wrong if running on different port
};

Error: "Application is requesting permissions without signature"

Symptoms:

{
  "accepted": false,
  "message": "Could not connect the application: Application is requesting permissions without signature"
}

Cause: You included a permissions object but didn't provide a valid DERO signature.

Solution: Either remove the permissions field, or provide a valid signature:

// Option 1: No pre-set permissions (recommended for most apps)
const applicationData = {
    "id": appId,
    "name": "My App",
    "description": "My application",
    "url": window.location.origin
    // No permissions field - user will be prompted for each method
};
 
// Option 2: With signature (advanced - requires wallet signing)
const applicationData = {
    "id": appId,
    "name": "My App",
    "description": "My application",
    "url": window.location.origin,
    "permissions": {
        "GetBalance": 3  // AlwaysAllow
    },
    "signature": "-----BEGIN DERO SIGNED MESSAGE-----\n..."  // Must sign the appId
};

Error: "WebSocket connection failed"

Symptoms:

WebSocket connection to 'ws://127.0.0.1:44326/xswd' failed

Common Causes:

  1. Wallet not running
  2. XSWD not enabled in wallet
  3. Wrong port
  4. Firewall blocking connection

Diagnosis:

// Test XSWD connectivity (use localhost to match app1 pattern)
function testXSWDPorts() {
    const ports = [44326, 10103, 40403];
    
    ports.forEach(port => {
        const ws = new WebSocket(`ws://localhost:${port}/xswd`);
        
        ws.onopen = () => {
            console.log(`✅ Port ${port} is accessible`);
            ws.close();
        };
        
        ws.onerror = () => {
            console.error(`❌ Port ${port} failed`);
        };
    });
}
 
testXSWDPorts();

Solutions:

  1. Check Wallet is Running

    # Check if Engram is running
    ps aux | grep -i engram
     
    # Or check DERO wallet
    ps aux | grep -i dero-wallet
  2. Enable XSWD in Engram

    • Open Engram wallet
    • Go to Settings → XSWD
    • Ensure "Enable XSWD" is checked
    • Check port (default: 44326)
  3. Try Alternative Ports

    const XSWD_ENDPOINTS = [
        'ws://127.0.0.1:44326/xswd',  // Engram default
        'ws://127.0.0.1:10103/xswd',  // Wallet RPC (mainnet)
        'ws://127.0.0.1:40403/xswd'   // Wallet RPC (testnet)
    ];
     
    async function connectWithFallback() {
        for (const endpoint of XSWD_ENDPOINTS) {
            try {
                const socket = new WebSocket(endpoint);
                await new Promise((resolve, reject) => {
                    socket.onopen = resolve;
                    socket.onerror = reject;
                    setTimeout(reject, 5000);  // 5s timeout
                });
                return socket;  // Success!
            } catch (e) {
                console.log(`Failed to connect to ${endpoint}`);
            }
        }
        throw new Error('All XSWD endpoints failed');
    }
  4. Check Firewall

    # macOS: Check if port is blocked
    sudo lsof -i :44326
     
    # Linux: Check firewall
    sudo ufw status
    sudo ufw allow 44326
     
    # Windows: Check Windows Defender Firewall
    # Allow inbound on port 44326

Error: "XSWD connection closed unexpectedly"

Symptoms:

XSWD connection closed (code: 1006)

Causes:

  1. Wallet crashed
  2. Network interruption
  3. Too many requests
  4. Timeout

Solution:

// Implement auto-reconnection
class XSWDConnection {
    constructor() {
        this.socket = null;
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = 10;
        this.reconnectDelay = 1000;
    }
    
    connect(url) {
        this.socket = new WebSocket(url);
        
        this.socket.onopen = () => {
            console.log('✅ XSWD connected');
            this.reconnectAttempts = 0;
            this.onConnected();
        };
        
        this.socket.onclose = (event) => {
            console.log('🔌 XSWD disconnected:', event.code);
            this.reconnect(url);
        };
        
        this.socket.onerror = (error) => {
            console.error('❌ XSWD error:', error);
        };
    }
    
    reconnect(url) {
        if (this.reconnectAttempts >= this.maxReconnectAttempts) {
            console.error('Max reconnection attempts reached');
            this.onMaxAttemptsReached();
            return;
        }
        
        this.reconnectAttempts++;
        const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
        
        console.log(`Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);
        
        setTimeout(() => {
            this.connect(url);
        }, delay);
    }
    
    onConnected() {
        // Override this
    }
    
    onMaxAttemptsReached() {
        // Override this
        alert('Unable to connect to DERO wallet. Please ensure your wallet is running and XSWD is enabled.');
    }
}

XSWD Error Codes Reference

The XSWD server returns standard JSON-RPC error codes. Understanding these helps diagnose issues quickly:

CodeMeaningCommon Cause
-32700Parse errorInvalid JSON in request
-32600Invalid requestMissing required fields
-32601Method not foundTypo in method name, or method not available
-32602Invalid paramsWrong parameter types or values
-32603Internal errorServer-side error
-32000 to -32099Server errorApplication-specific errors

Rate Limiting: The XSWD server enforces a rate limit of 10 requests per second with a burst allowance of 20 requests. Exceeding this will result in requests being dropped or delayed.

Error: "Method not found"

Symptoms:

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32601,
    "message": "Method not found"
  }
}

Causes:

  1. Typo in method name
  2. Method not available in DERO version
  3. Wrong RPC endpoint

Solution:

// Validate method before calling
const AVAILABLE_METHODS = [
    'DERO.GetInfo',
    'DERO.GetBlock',
    'DERO.GetHeight',
    'DERO.GetSC',
    'GetAddress',
    'GetBalance',
    'Transfer',
    // ... add more
];
 
async function safeCall(method, params = {}) {
    // Check if method is known
    if (!AVAILABLE_METHODS.includes(method)) {
        console.warn(`Method ${method} might not be available`);
    }
    
    try {
        return await xswd.call(method, params);
    } catch (error) {
        if (error.code === -32601) {
            console.error(`Method ${method} not found. Check DERO version.`);
            // Try alternative method if available
            const alternative = getAlternativeMethod(method);
            if (alternative) {
                console.log(`Trying alternative: ${alternative}`);
                return await xswd.call(alternative, params);
            }
        }
        throw error;
    }
}

Deployment Errors

Error: "Simulator daemon crashed" or Daemon Crash During Deployment

Symptoms:

Simulator daemon crashed. Please restart simulator mode.
[OK] Transaction sent: d14b0a7b4c09bb4c98ab3b1d7fa1e19b61c9e79b0afa0002e529426edf17afb5
[WAIT] Waiting for block confirmation (HTTP polling)...
[ERR] DERO.GetInfo failed: HTTP request failed: dial tcp 127.0.0.1:20000: connect: connection refused

The daemon crashes immediately after sending a transaction, and subsequent RPC calls fail with "connection refused".

💥

Critical Issue: This is often caused by Unicode characters in your deployment files. The DERO daemon or Graviton database cannot process certain UTF-8 multi-byte characters, causing a crash.

Common Causes:

  1. Unicode characters in JavaScript, HTML, or CSS files
  2. Smart quotes copied from word processors
  3. Emojis in comments or strings
  4. Non-ASCII characters in any file content

Diagnosis:

# Check if files contain non-ASCII characters
file your-file.js your-file.css your-file.html
 
# Output should show "ASCII text" for all files
# If you see "UTF-8 Unicode text", you have Unicode characters
 
# Find non-ASCII characters
grep -P "[^\x00-\x7F]" your-file.js
 
# Or use this to show line numbers
grep -n -P "[^\x00-\x7F]" *.js *.css *.html

Common Unicode Culprits in Code:

CharacterUnicodeASCII Replacement
" " (smart quotes)U+201C, U+201D"
' ' (smart apostrophes)U+2018, U+2019'
(em dash)U+2014--
(en dash)U+2013-
(ellipsis)U+2026...
(arrow)U+2192-> or =>
× (multiply)U+00D7* or x
U+2265, U+2264>= <=
(bullet)U+2022* or -

Solution:

  1. Replace Unicode with ASCII equivalents:
// Before (has Unicode)
const message = "Hello — world";  // Em dash
const quote = 'It's working';     // Smart apostrophe
 
// After (ASCII only)
const message = "Hello -- world"; // Double hyphen
const quote = "It's working";     // Straight apostrophe
  1. Use sed to fix common issues:
# Replace smart quotes
sed -i '' "s/'/'/g; s/'/'/g; s/"/\"/g; s/"/\"/g" *.js *.html
 
# Replace em/en dashes
sed -i '' 's/—/--/g; s/–/-/g' *.js *.html
 
# Replace ellipsis
sed -i '' 's/…/.../g' *.js *.html
  1. Verify files are ASCII:
# After fixing, verify all files are ASCII
file *.js *.css *.html | grep -v "ASCII"
# Should return nothing (all files are ASCII)
  1. Prevent future issues:
    • Configure your editor to use straight quotes
    • Disable "smart quotes" in your OS settings
    • Use a linter that warns about non-ASCII characters

Error: "File too large"

Symptoms:

Error: DOC file exceeds maximum size of 18KB

Diagnosis:

# Check file size
ls -lh your-file.html
 
# Check actual code size (without whitespace)
# Minified size is what matters
cat your-file.html | tr -d ' \n\t' | wc -c

Solutions:

  1. Minify Code

    # HTML minification
    # Remove comments, whitespace
    sed -e 's/<!--.*-->//g' -e 's/  */ /g' input.html > output.html
     
    # CSS minification
    npx cssnano input.css output.min.css
     
    # JavaScript minification
    npx terser input.js -o output.min.js -c -m
  2. Enable Compression

    » install-doc
    # ...
    Compress file data (y/n) » y  # Always say yes!
  3. Split into Multiple DOCs

    // Main DOC (index.html) - UI only
    // DOC 2 (utils.js) - Utilities
    // DOC 3 (charts.js) - Charts library
     
    // Load additional DOCs dynamically
    async function loadModule(scid) {
        const content = await fetchTELADoc(scid);
        eval(content);  // Load the module
    }
  4. Remove Unused Code

    // ❌ Including entire library
    <script src="lodash.min.js"></script>  // 70KB!
     
    // ✅ Include only what you need
    function debounce(fn, wait) { /* ... */ }  // 200 bytes

Error: "Expecting declaration of function but found ':'" or "File contains '*/' which breaks TELA deployment"

Symptoms:

Error: [-32098] Expecting declaration of function but found ":"

or

Error: File contains '*/' which breaks TELA deployment
💥

Critical Issue: TELA wraps your code in a DVM-BASIC comment block. If your file contains */ (even in a string or CSS comment), it prematurely closes the wrapper comment and the parser tries to read your code as DVM-BASIC syntax, causing deployment to fail.

Why This Happens:

TELA stores your file content inside a DVM-BASIC comment block like this:

' Your code is wrapped like this:
' /* Your entire file content here */
' */

If your file contains */, it closes the wrapper comment early:

' /* Your file starts here...
'   /* Some CSS comment */
'   */  ← This closes the wrapper comment!
'   .my-class { color: red; }  ← Now parser thinks this is DVM-BASIC → ERROR!

Common Causes:

  1. CSS comment blocks - /* DERO Explorer v2.0 */
  2. JavaScript multi-line comments - /* This is a comment */
  3. String literals containing */ - const pattern = "*/";
  4. Regular expressions - const regex = /\*/;

Diagnosis:

# Find all occurrences of '*/' in your files
grep -n '\*/' *.css *.js *.html
 
# Check for CSS comments specifically
grep -n '/\*' *.css
 
# Check for JavaScript multi-line comments
grep -n '/\*' *.js

Solution:

  1. Remove CSS comment blocks:

    /* ❌ Before - breaks TELA */
    /* DERO Explorer v2.0 - Base Styles */
    :root { --color: #000; }
     
    /* ✅ After - safe */
    :root { --color: #000; }
  2. Replace JavaScript multi-line comments with single-line:

    /* ❌ Before - breaks TELA */
    /* This is a long comment
       explaining something */
    function myFunc() { }
     
    /* ✅ After - safe */
    // This is a long comment
    // explaining something
    function myFunc() { }
  3. Fix string literals containing */:

    // ❌ Before - breaks TELA
    if (line.startsWith('*/')) { }
     
    // ✅ After - safe (string concatenation)
    if (line.startsWith('*' + '/')) { }
  4. Fix regular expressions:

    // ❌ Before - breaks TELA
    const regex = /\*/;
     
    // ✅ After - safe (escape or use string)
    const regex = /\*\//;  // Escaped
    // OR
    const regex = new RegExp('\\*/');  // String constructor
  5. Automated fix for CSS files:

    # Remove all CSS comment blocks
    sed -i '' 's|/\*[^*]*\*/||g' *.css
     
    # Or more comprehensive (handles nested comments)
    sed -i '' 's|/\*[^*]*\*\([^/*][^*]*\*\)*/||g' *.css
  6. Automated fix for JavaScript files:

    # Remove multi-line comments (be careful with strings!)
    # Better to do this manually or use a proper minifier
    npx terser input.js -o output.js --comments false

Best Practice:

  • CSS: Remove all /* */ comment blocks before deployment
  • JavaScript: Use // single-line comments instead of /* */
  • Always: Test deployment in simulator mode first to catch these issues early

Prevention:

  • Configure your build process to strip comments automatically
  • Use TELA-CLI's compression feature which handles this automatically
  • Add a pre-deployment check:
    # Check for problematic patterns
    if grep -q '\*/' *.css *.js; then
        echo "ERROR: Files contain '*/' which breaks TELA deployment"
        exit 1
    fi

Error: "Invalid SCID format"

Symptoms:

Error: SCID must be 64 hexadecimal characters

Causes:

  1. Typo in SCID
  2. Copied with extra characters
  3. Wrong SCID type (TXID instead of SCID)

Solution:

// Validate SCID format
function validateSCID(scid) {
    // Remove any whitespace
    scid = scid.trim();
    
    // Check length
    if (scid.length !== 64) {
        throw new Error(`Invalid SCID length: ${scid.length} (expected 64)`);
    }
    
    // Check if hexadecimal
    if (!/^[a-f0-9]{64}$/i.test(scid)) {
        throw new Error('SCID must contain only hexadecimal characters');
    }
    
    return scid.toLowerCase();
}
 
// Usage
try {
    const cleanSCID = validateSCID(userInput);
    await deployIndex(cleanSCID);
} catch (error) {
    alert(error.message);
}

Error: "Insufficient funds"

Symptoms:

Error: Insufficient balance for transaction
Required: 5.5 DERO
Available: 2.0 DERO

Solution:

  1. Check Balance

    # In TELA-CLI
    » wallet
    # Check balance displayed
     
    # Or via XSWD
    const balance = await xswd.call('GetBalance');
    console.log('Balance:', balance.balance / 100000, 'DERO');
  2. Get More DERO

  3. Reduce Transaction Cost

   # Optimize file size to reduce storage cost
   # Every 1KB saved ≈ 0.3 DERO saved

Error: "Transaction rejected"

Symptoms:

Error: Transaction validation failed

Causes:

  1. Invalid parameters
  2. Smart contract error
  3. Network congestion
  4. Ringsize too small

Solution:

# Check transaction parameters
» install-doc
# Verify:
# - File path is correct
# - File is readable
# - Ringsize >= 2
# - Valid compression setting
 
# Try again with ringsize 2 (minimum)
Enter DOC install ringsize » 2

File Size Errors

Error: "Code size exceeds 18KB after processing"

Diagnosis:

// Calculate actual code size
function calculateCodeSize(html) {
    // Remove whitespace and comments
    let code = html
        .replace(/<!--[\s\S]*?-->/g, '')  // Remove HTML comments
        .replace(/\/\*[\s\S]*?\*\//g, '')  // Remove CSS comments
        .replace(/\/\/.*/g, '')            // Remove JS comments
        .replace(/\s+/g, ' ')              // Normalize whitespace
        .trim();
    
    const bytes = new Blob([code]).size;
    const kb = (bytes / 1024).toFixed(2);
    
    console.log(`Code size: ${kb} KB (${bytes} bytes)`);
    return bytes;
}

Solutions:

  1. Aggressive Minification

    // Use variable name shortening
    // Before:
    function calculateTotalPrice(items) {
        let totalPrice = 0;
        for (const item of items) {
            totalPrice += item.price;
        }
        return totalPrice;
    }
     
    // After:
    const c=(i)=>i.reduce((t,x)=>t+x.p,0);
  2. Use DocShards

   # For files > 18KB, use DocShards system
   » install-shards
   Enter file path » large-file.js
   # Automatically splits into multiple DOCs
  1. External Resources via TELA Links
    // Store large resources in separate DOCs
    // Reference via TELA links
    const CHART_LIB_SCID = 'abc123...';
     
    async function loadChartLibrary() {
        const lib = await fetchTELADoc(CHART_LIB_SCID);
        eval(lib);
    }

Runtime Errors

Error: "Cannot read property of undefined"

Symptoms:

Uncaught TypeError: Cannot read property 'height' of undefined

Causes:

  1. API call failed silently
  2. Network timing issue
  3. Missing null check

Solution:

// ❌ BAD: No error handling
async function getBlockHeight() {
    const info = await xswd.call('DERO.GetInfo');
    return info.height;  // What if info is undefined?
}
 
// ✅ GOOD: Defensive programming
async function getBlockHeight() {
    try {
        const info = await xswd.call('DERO.GetInfo');
        
        // Check if response is valid
        if (!info || typeof info !== 'object') {
            throw new Error('Invalid response from GetInfo');
        }
        
        // Use optional chaining and nullish coalescing
        return info?.height ?? 0;
        
    } catch (error) {
        console.error('Failed to get block height:', error);
        return 0;  // Safe default
    }
}

Error: "Promise rejection unhandled"

Symptoms:

Unhandled Promise Rejection: Error: Network error

Solution:

// ❌ BAD: No catch handler
xswd.call('DERO.GetInfo').then(info => {
    updateUI(info);
});
 
// ✅ GOOD: Always handle rejections
xswd.call('DERO.GetInfo')
    .then(info => {
        updateUI(info);
    })
    .catch(error => {
        console.error('GetInfo failed:', error);
        showError('Unable to fetch network information');
    });
 
// ✅ BETTER: Use async/await with try/catch
async function fetchNetworkInfo() {
    try {
        const info = await xswd.call('DERO.GetInfo');
        updateUI(info);
    } catch (error) {
        console.error('GetInfo failed:', error);
        showError('Unable to fetch network information');
    }
}
 
// ✅ BEST: Global unhandled rejection handler
window.addEventListener('unhandledrejection', event => {
    console.error('Unhandled promise rejection:', event.reason);
    event.preventDefault();  // Prevent default console error
});

Error: "Memory leak detected"

Symptoms:

  • Browser tab memory usage increases over time
  • Page becomes slow after being open for hours
  • Eventually browser crashes

Diagnosis:

// Monitor memory usage
setInterval(() => {
    if (performance.memory) {
        const mb = (performance.memory.usedJSHeapSize / 1048576).toFixed(2);
        console.log(`Memory: ${mb} MB`);
        
        if (mb > 100) {
            console.warn('⚠️ High memory usage!');
            // Trigger cleanup if possible
        }
    }
}, 30000);  // Check every 30 seconds

Solution:

// Common memory leak causes and fixes
 
// 1. ❌ BAD: Not clearing intervals
setInterval(() => {
    updateData();
}, 1000);
 
// ✅ GOOD: Track and clear intervals
const intervals = [];
 
function startUpdates() {
    const id = setInterval(() => updateData(), 1000);
    intervals.push(id);
}
 
function cleanup() {
    intervals.forEach(id => clearInterval(id));
    intervals.length = 0;
}
 
window.addEventListener('beforeunload', cleanup);
 
// 2. ❌ BAD: Not removing event listeners
element.addEventListener('click', handler);
 
// ✅ GOOD: Remove when done
element.addEventListener('click', handler);
// Later:
element.removeEventListener('click', handler);
 
// 3. ❌ BAD: Storing references indefinitely
const cache = new Map();
function cacheData(key, value) {
    cache.set(key, value);  // Never cleared!
}
 
// ✅ GOOD: Clear old cache entries
const cache = new Map();
const CACHE_MAX_SIZE = 100;
 
function cacheData(key, value) {
    cache.set(key, value);
    
    // Evict oldest entries if cache too large
    if (cache.size > CACHE_MAX_SIZE) {
        const firstKey = cache.keys().next().value;
        cache.delete(firstKey);
    }
}

Network & Blockchain Errors

Error: "Block not found"

Symptoms:

{
  "error": {
    "code": -32000,
    "message": "Block not found"
  }
}

Causes:

  1. Block height doesn't exist yet
  2. Blockchain not synced
  3. Invalid block hash

Solution:

async function getBlockSafely(height) {
    try {
        // First check current height
        const info = await xswd.call('DERO.GetHeight');
        
        if (height > info.height) {
            throw new Error(`Block ${height} doesn't exist yet. Current height: ${info.height}`);
        }
        
        const block = await xswd.call('DERO.GetBlock', { height });
        return block;
        
    } catch (error) {
        console.error(`Failed to get block ${height}:`, error);
        
        // Provide helpful error message
        if (error.message.includes('not found')) {
            showError(`Block ${height} not found. The blockchain might still be syncing.`);
        } else {
            showError('Unable to fetch block data');
        }
        
        return null;
    }
}

Error: "Node not synced"

Symptoms:

Warning: Node is not fully synced
Current: 10000 / Target: 25000

Solution:

// Check sync status before critical operations
async function waitForSync(maxWaitMs = 60000) {
    const startTime = Date.now();
    
    while (Date.now() - startTime < maxWaitMs) {
        const info = await xswd.call('DERO.GetInfo');
        
        // Check if synced (height matches topoheight)
        if (Math.abs(info.height - info.topoheight) <= 1) {
            console.log('✅ Node is synced');
            return true;
        }
        
        console.log(`Syncing: ${info.height} / ${info.topoheight}`);
        await new Promise(resolve => setTimeout(resolve, 5000));
    }
    
    console.warn('⚠️ Sync timeout - proceeding anyway');
    return false;
}
 
// Usage
await waitForSync();
// Now safe to query blockchain

Error: "Network timeout"

Symptoms:

Error: Request timeout after 30000ms

Solution:

// Implement request timeout with retry
async function callWithRetry(method, params, maxRetries = 3) {
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
        try {
            // Set timeout
            const timeoutMs = 30000;  // 30 seconds
            const timeoutPromise = new Promise((_, reject) => {
                setTimeout(() => reject(new Error('Timeout')), timeoutMs);
            });
            
            // Race between call and timeout
            const result = await Promise.race([
                xswd.call(method, params),
                timeoutPromise
            ]);
            
            return result;
            
        } catch (error) {
            console.warn(`Attempt ${attempt} failed:`, error.message);
            
            if (attempt === maxRetries) {
                throw new Error(`Failed after ${maxRetries} attempts`);
            }
            
            // Exponential backoff
            const delay = Math.min(1000 * Math.pow(2, attempt), 10000);
            console.log(`Retrying in ${delay}ms...`);
            await new Promise(resolve => setTimeout(resolve, delay));
        }
    }
}

Performance Issues

Issue: "Slow page load (> 5 seconds)"

Diagnosis:

// Measure load time
const observer = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
        if (entry.entryType === 'navigation') {
            console.log('Load breakdown:');
            console.log('DNS:', entry.domainLookupDuration, 'ms');
            console.log('TCP:', entry.connectDuration, 'ms');
            console.log('Request:', entry.requestDuration, 'ms');
            console.log('Response:', entry.responseDuration, 'ms');
            console.log('DOM Processing:', entry.domComplete - entry.domInteractive, 'ms');
            console.log('Total:', entry.duration, 'ms');
        }
    }
});
 
observer.observe({ entryTypes: ['navigation'] });

Solutions:

  1. Defer Non-Critical JS

    <script src="critical.js"></script>
    <script src="charts.js" defer></script>
    <script src="analytics.js" defer></script>
  2. Lazy Load Images

    <img src="placeholder.png" data-src="actual-image.png" loading="lazy">
  3. Minimize Rendering Blocking

    <!-- ❌ Blocks rendering -->
    <link rel="stylesheet" href="styles.css">
     
    <!-- ✅ Non-blocking -->
    <link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'">

Development Environment Issues

Error: "TELA-CLI not found"

Solution:

# Check if TELA-CLI is in PATH
which tela-cli
 
# If not found, add to PATH
export PATH=$PATH:/path/to/tela-dev/cmd/tela-cli
 
# Or create alias
alias tela-cli='/path/to/tela-dev/cmd/tela-cli/tela-cli'
 
# Or run directly
cd /path/to/tela-dev/cmd/tela-cli
./tela-cli

Error: "Go build failed"

Symptoms:

Error: cannot find package "github.com/deroproject/derohe"

Solution:

# Update Go modules
cd tela-dev
go mod tidy
go mod download
 
# Rebuild
cd cmd/tela-cli
go build
 
# If still failing, check Go version
go version  # Should be 1.17 or higher
 
# Update Go if needed
# https://golang.org/doc/install

Diagnostic Tools

Quick Diagnostic Script

// Add to your application for debugging
async function runDiagnostics() {
    console.log('🔍 Running TELA diagnostics...\n');
    
    const results = {
        browser: {},
        xswd: {},
        blockchain: {},
        performance: {}
    };
    
    // Browser checks
    results.browser.userAgent = navigator.userAgent;
    results.browser.webSocketSupport = typeof WebSocket !== 'undefined';
    results.browser.localStorageSupport = typeof localStorage !== 'undefined';
    
    // XSWD checks (use localhost to match app1 pattern)
    try {
        const testSocket = new WebSocket('ws://localhost:44326/xswd');
        await new Promise((resolve, reject) => {
            testSocket.onopen = resolve;
            testSocket.onerror = reject;
            setTimeout(reject, 5000);
        });
        results.xswd.connected = true;
        testSocket.close();
    } catch (e) {
        results.xswd.connected = false;
        results.xswd.error = e.message;
    }
    
    // Blockchain checks
    if (results.xswd.connected) {
        try {
            const info = await xswd.call('DERO.GetInfo');
            results.blockchain.height = info.height;
            results.blockchain.synced = Math.abs(info.height - info.topoheight) <= 1;
            results.blockchain.version = info.version;
        } catch (e) {
            results.blockchain.error = e.message;
        }
    }
    
    // Performance checks
    if (performance.memory) {
        results.performance.memoryMB = (performance.memory.usedJSHeapSize / 1048576).toFixed(2);
    }
    results.performance.connectionType = navigator.connection?.effectiveType;
    
    console.log('Diagnostics Results:');
    console.log(JSON.stringify(results, null, 2));
    
    return results;
}

Getting Help

When reporting issues, include:

  1. Error Message (complete error text)
  2. Environment (browser, OS, DERO version)
  3. Steps to Reproduce
  4. Diagnostic Results (from script above)
  5. Expected vs Actual Behavior

Support Channels:

💡

Pro Tip: Before reporting an issue, run the diagnostic script and include the results. It helps maintainers debug issues faster!


Additional Resources


Verified Demo Reference

Working Examples for Reference: