✨Works out of the box guarantee. If you face any issue at all, hit us up on Telegram and we will write the integration for you.
logoReclaim Protocol Docs

Troubleshooting

Common issues and solutions when integrating the Reclaim JavaScript SDK

Common Issues

This guide covers the most common issues developers encounter when integrating the Reclaim JavaScript SDK and their solutions.


Installation Issues

Module Not Found Error

Problem: Cannot find module '@reclaimprotocol/js-sdk'

Solutions:

  1. Verify the package is installed:

    npm list @reclaimprotocol/js-sdk
  2. Reinstall the package:

    npm install @reclaimprotocol/js-sdk
  3. Clear cache and reinstall:

    rm -rf node_modules package-lock.json
    npm install
  4. Check your package.json includes the dependency:

    {
      "dependencies": {
        "@reclaimprotocol/js-sdk": "^latest"
      }
    }

TypeScript Type Errors

Problem: TypeScript can't find type definitions

Solutions:

  1. Ensure TypeScript 4.0 or later:

    npm install --save-dev typescript@latest
  2. Check tsconfig.json settings:

    {
      "compilerOptions": {
        "moduleResolution": "node",
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true
      }
    }
  3. Import types explicitly:

    import { ReclaimProofRequest, Proof } from '@reclaimprotocol/js-sdk';

Initialization Issues

Invalid Credentials Error

Problem: Invalid credentials or 401 Unauthorized when initializing SDK

Solutions:

  1. Verify your credentials are correct:

    • Check APP_ID matches the one in Reclaim Developer Portal
    • Verify APP_SECRET is correct (copy-paste to avoid typos)
    • Confirm PROVIDER_ID is from the same application
  2. Check environment variables are loaded:

    console.log('APP_ID:', process.env.RECLAIM_APP_ID);
    console.log('APP_SECRET exists:', !!process.env.RECLAIM_APP_SECRET);
  3. Ensure .env file is in the correct location (project root for most frameworks)

  4. Restart your development server after changing .env files

Provider Not Found Error

Problem: Provider not found or 404 error

Solutions:

  1. Verify the provider is added to your application in the Reclaim Developer Portal

  2. Check the PROVIDER_ID matches exactly (case-sensitive)

  3. Ensure the provider is active and not disabled


Frontend Issues

Problem: Calling triggerReclaimFlow() but nothing shows up

Solutions:

  1. Ensure you're calling it from a user interaction (button click):

    // ✅ Correct - from user interaction
    button.addEventListener('click', async () => {
      await reclaimProofRequest.triggerReclaimFlow();
    });
     
    // ❌ Wrong - auto-triggered on page load
    await reclaimProofRequest.triggerReclaimFlow(); // Browser may block
  2. Check browser console for errors

  3. Verify SDK initialization completed before triggering flow

  4. Test in a different browser (some ad blockers may interfere)

QR Code Not Loading

Problem: QR code is blank or shows an error

Solutions:

  1. Verify getRequestUrl() returns a valid URL:

    const url = await reclaimProofRequest.getRequestUrl();
    console.log('Request URL:', url); // Should be a valid https:// URL
  2. Check QR code library is installed (if using custom QR):

    npm install react-qr-code
    # or
    npm install qrcode.react
  3. Ensure request URL is not too long (if it is, provider config may be invalid)

Proofs Not Received (onSuccess Never Called)

Problem: User completes verification but onSuccess callback doesn't fire

Solutions:

  1. Ensure startSession() is called BEFORE user completes verification:

    // ✅ Correct order
    await reclaimProofRequest.triggerReclaimFlow();
    await reclaimProofRequest.startSession({ onSuccess, onError });
     
    // ❌ Wrong order
    await reclaimProofRequest.startSession({ onSuccess, onError });
    await reclaimProofRequest.triggerReclaimFlow(); // Too late
  2. Check network connection (proofs are delivered via WebSocket)

  3. Look for WebSocket errors in browser console

  4. Verify callback functions are defined:

    await reclaimProofRequest.startSession({
      onSuccess: (proofs) => {
        console.log('✅ This should fire', proofs);
      },
      onError: (error) => {
        console.log('❌ Or this should fire', error);
      }
    });

Mobile Verification Fails

Problem: App Clip or Instant App doesn't launch on mobile

Solutions:

  1. Test on an actual mobile device (simulators may not support App Clips/Instant Apps)

  2. Ensure you're testing on supported platforms:

    • iOS 14+ for App Clips
    • Android 6.0+ (API 23+) for Instant Apps
  3. Check that you're using a real mobile browser (not desktop browser in mobile mode)

  4. Verify the request URL is accessible from the mobile device


Backend Issues

CORS Errors

Problem: Access to fetch blocked by CORS policy

Solutions:

  1. Express.js: Install and configure CORS middleware:

    const cors = require('cors');
     
    app.use(cors({
      origin: process.env.NODE_ENV === 'production'
        ? 'https://yourapp.com'
        : 'http://localhost:3000',
      credentials: true
    }));
  2. Next.js API Routes: CORS is handled automatically for same-origin requests. For cross-origin:

    export async function GET(request) {
      const response = NextResponse.json({ data });
      response.headers.set('Access-Control-Allow-Origin', '*');
      return response;
    }
  3. FastAPI:

    from fastapi.middleware.cors import CORSMiddleware
     
    app.add_middleware(
      CORSMiddleware,
      allow_origins=["http://localhost:3000"],
      allow_credentials=True,
      allow_methods=["*"],
      allow_headers=["*"],
    )

Callback Endpoint Not Reached

Problem: Backend callback URL is never called after verification

Solutions:

  1. Verify callback URL is publicly accessible:

    # Test from external service
    curl https://yourapp.com/api/reclaim/callback
  2. For local development, use ngrok:

    ngrok http 3000
    # Update BASE_URL in .env to ngrok URL
  3. Check ngrok is running and tunnel is active

  4. Verify BASE_URL in environment variables:

    console.log('Callback URL:', `${process.env.BASE_URL}/api/reclaim/callback`);
  5. Check for trailing slashes - ensure consistency:

    // ✅ Correct
    setAppCallbackUrl(`${BASE_URL}/api/reclaim/callback`);
     
    // ❌ May cause issues
    setAppCallbackUrl(`${BASE_URL}//api/reclaim/callback`); // Double slash
  6. Monitor server logs for incoming requests

Proof Parsing Fails

Problem: JSON.parse() fails when processing proof in callback

Solutions:

  1. Express.js: Use express.text() middleware:

    app.use(express.text({ type: '*/*', limit: '50mb' }));
     
    app.post('/api/reclaim/callback', async (req, res) => {
      const decodedBody = decodeURIComponent(req.body);
      const proof = JSON.parse(decodedBody);
      // ...
    });
  2. Next.js (Pages Router): Disable body parser:

    export const config = {
      api: {
        bodyParser: false,
      },
    };
  3. Next.js (App Router): Read raw text:

    const body = await request.text();
    const decodedBody = decodeURIComponent(body);
    const proof = JSON.parse(decodedBody);
  4. FastAPI:

    body = await request.body()
    body_str = body.decode('utf-8')
    body_str = unquote(body_str)
    proof = json.loads(body_str)

Environment Variables Not Loading

Problem: process.env.RECLAIM_APP_ID is undefined

Solutions:

  1. Node.js: Install and use dotenv:

    require('dotenv').config(); // At the very top of your file
  2. Next.js: Ensure file is named .env.local and restart dev server

  3. Verify file location: .env should be in project root

  4. Check .env syntax:

    # ✅ Correct
    RECLAIM_APP_ID=your_app_id
     
    # ❌ Wrong
    RECLAIM_APP_ID = your_app_id  # No spaces around =
    RECLAIM_APP_ID="your_app_id"  # No quotes needed
  5. Restart server after modifying .env files


Verification Issues

Proof Verification Fails

Problem: verifyProof() returns false

Solutions:

  1. Ensure proof structure is correct:

    console.log('Proof structure:', {
      hasIdentifier: !!proof.identifier,
      hasClaimData: !!proof.claimData,
      hasSignatures: Array.isArray(proof.signatures),
      hasWitnesses: Array.isArray(proof.witnesses)
    });
  2. Check proof hasn't been tampered with during transmission

  3. Verify proof is from the correct provider

  4. Ensure SDK versions match between frontend and backend

Timeout Errors

Problem: Verification times out or takes too long

Solutions:

  1. Check network connectivity on mobile device

  2. Verify provider is responding:

    • Some providers may be temporarily unavailable
    • Try a different provider to test
  3. Increase timeout if needed (though default should be sufficient)

  4. Check user completed the flow - they may have abandoned it


Development Environment Issues

Hot Reload Issues

Problem: Changes to code aren't reflected after saving

Solutions:

  1. Hard refresh browser: Ctrl+Shift+R (Windows/Linux) or Cmd+Shift+R (Mac)

  2. Clear browser cache and reload

  3. Restart development server

  4. Check build tool console for errors

Build Errors

Problem: Build fails with SDK-related errors

Solutions:

  1. Next.js: If encountering SSR issues, use dynamic imports:

    const { ReclaimProofRequest } = await import('@reclaimprotocol/js-sdk');
  2. Vite: Ensure SDK is not being pre-bundled incorrectly:

    // vite.config.js
    export default {
      optimizeDeps: {
        include: ['@reclaimprotocol/js-sdk']
      }
    }
  3. Webpack: Check module resolution settings

ngrok Issues

Problem: ngrok tunnel not working or disconnecting

Solutions:

  1. Verify ngrok is running: Check terminal where ngrok was started

  2. ngrok free tier limitations:

    • URL changes on each restart
    • Session timeout after inactivity
    • Consider paid tier for persistent URL
  3. Update BASE_URL after restarting ngrok

  4. Alternative: Use other tunneling tools like:

    • localtunnel: npx localtunnel --port 3000
    • CloudFlare Tunnel
    • serveo.net

Production Issues

Vercel Deployment Issues

Problem: Works locally but fails on Vercel

Solutions:

  1. Set environment variables in Vercel dashboard:

    • Go to Project Settings → Environment Variables
    • Add all required variables
  2. Check BASE_URL is set correctly:

    const baseUrl = process.env.VERCEL_URL
      ? `https://${process.env.VERCEL_URL}`
      : process.env.NEXT_PUBLIC_BASE_URL;
  3. Verify API routes are in correct location for deployment

  4. Check function logs in Vercel dashboard for errors

Heroku/Railway Deployment Issues

Problem: Callback not working on Heroku/Railway

Solutions:

  1. Use dynamic PORT:

    const PORT = process.env.PORT || 3000;
  2. Set BASE_URL to your app URL:

    # On Heroku
    heroku config:set BASE_URL=https://yourapp.herokuapp.com
  3. Check dyno/service logs for errors


Security Issues

APP_SECRET Exposed

Problem: APP_SECRET was accidentally committed to git

Solutions:

  1. Immediately rotate your credentials in Reclaim Developer Portal

  2. Remove from git history:

    # Use git filter-branch or BFG Repo-Cleaner
    # Or delete and recreate repository if necessary
  3. Add to .gitignore:

    .env
    .env.local
    .env.*.local
  4. Audit code to ensure no other secrets are exposed


Getting Help

If you've tried the solutions above and still experiencing issues:

Before Asking for Help

  1. Check browser console for error messages
  2. Check server logs for backend errors
  3. Verify all credentials are correct
  4. Test with a minimal example to isolate the issue
  5. Check SDK version is up to date:
    npm update @reclaimprotocol/js-sdk

Where to Get Help

Providing Information

When asking for help, include:

  1. SDK version: Check package.json
  2. Framework and version: React 18, Next.js 14, etc.
  3. Error messages: Full error from console/logs
  4. Code snippet: Minimal reproducible example
  5. Environment: Browser, OS, Node.js version
  6. Steps to reproduce: What you did before the error

Debugging Tips

Enable Verbose Logging

// Add detailed logging
const reclaimProofRequest = await ReclaimProofRequest.init(...);
 
console.log('Initialized:', reclaimProofRequest);
 
const requestUrl = await reclaimProofRequest.getRequestUrl();
console.log('Request URL:', requestUrl);
 
await reclaimProofRequest.startSession({
  onSuccess: (proofs) => {
    console.log('✅ Success:', JSON.stringify(proofs, null, 2));
  },
  onError: (error) => {
    console.error('❌ Error:', error);
    console.error('Error stack:', error.stack);
  }
});

Test in Isolation

Create a minimal test file to isolate the issue:

// test-reclaim.js
import { ReclaimProofRequest } from '@reclaimprotocol/js-sdk';
 
async function test() {
  try {
    console.log('Step 1: Initializing...');
    const request = await ReclaimProofRequest.init(
      process.env.RECLAIM_APP_ID,
      process.env.RECLAIM_APP_SECRET,
      process.env.RECLAIM_PROVIDER_ID
    );
    console.log('✅ Initialized');
 
    console.log('Step 2: Getting URL...');
    const url = await request.getRequestUrl();
    console.log('✅ URL:', url);
 
    // Continue testing...
  } catch (error) {
    console.error('❌ Failed:', error);
  }
}
 
test();

Next Steps