Skip to main content

Quick Diagnostics

Having issues? Start here:
1

Check Status

Verify each part of the pipeline:
  • ✅ Extension deployed? Check Fly.io logs
  • ✅ Extension released? Check Shopify versions
  • ✅ Added to checkout? Check editor settings
  • ✅ Code correct? Review validation output
2

Review Logs

Check for errors:
  • Browser console (F12)
  • Fly.io deployment logs
  • Shopify function logs
  • GitHub Actions output
3

Test Locally

Reproduce the issue:
npm run dev
# Test in local environment
4

Consult This Guide

Find your issue below and follow the solution

Extension Issues

Symptoms:
  • Extension doesn’t show in checkout
  • Deployment succeeded but nothing visible
  • Works locally but not in production
Solution 1: Add to Checkout Editor
  1. Go to Settings → Checkout → Customize
  2. Look in left sidebar for your extension
  3. Drag extension into desired location
  4. Click Save
Solution 2: Check Extension TargetVerify target matches your use case:
# shopify.extension.toml
[[extensions.targeting]]
target = "purchase.checkout.delivery-address.render-after"
Common targets:
  • purchase.checkout.delivery-address.render-after
  • purchase.checkout.payment-method-list.render-after
  • purchase.checkout.block.render
  • purchase.checkout.cart-line-item.render-after
Solution 3: Verify Release Status
shopify app versions list
Ensure version is “current” not “draft”Solution 4: Check Conditional RenderingReview your code for conditions that might hide it:
// This might be hiding your extension!
if (!address) return null;
if (cartTotal < 50) return null;
if (someCondition) return null;
Symptoms:
  • Extension space is visible but empty
  • No content renders
  • No console errors
Solution 1: Check for Early Returns
function Extension() {
  const data = useData();
  
  // Add logging
  console.log('Extension rendering', { data });
  
  // Check all return paths
  if (!data) {
    console.log('No data, showing loading');
    return <SkeletonText />;  // Don't return null
  }
  
  return <Content data={data} />;
}
Solution 2: Verify Component Imports
// ❌ Wrong import
import { Text } from 'react';

// ✅ Correct import
import { Text } from '@shopify/ui-extensions-react/checkout';
Solution 3: Check for ErrorsWrap in error boundary:
<ErrorBoundary onError={(e) => console.error(e)}>
  <Extension />
</ErrorBoundary>
Symptoms:
  • Hook returns undefined
  • Data doesn’t populate
  • GraphQL query returns null
Solution 1: Verify GraphQL QueryCheck run.graphql syntax:
# ❌ Wrong field name
query RunInput {
  cart {
    deliveryAddress {  # Field doesn't exist
      country
    }
  }
}

# ✅ Correct
query RunInput {
  cart {
    deliveryGroups {
      deliveryAddress {
        countryCode
      }
    }
  }
}
Solution 2: Test Query in GraphiQL
shopify app graphiql
Paste your query and verify it worksSolution 3: Add Null Checks
function Extension() {
  const address = useShippingAddress();
  
  // ❌ Assumes address exists
  const country = address.country;
  
  // ✅ Handles null/undefined
  const country = address?.countryCode ?? 'US';
  
  // ✅ Returns early
  if (!address) {
    return <Text>Please enter shipping address</Text>;
  }
  
  const country = address.countryCode;
}
Symptoms:
  • Build fails with type errors
  • Red squiggles in IDE
  • “Type X is not assignable to type Y”
Solution 1: Add Type Guards
// ❌ Error: string | undefined not assignable to string
const country: string = address.country;

// ✅ Fix with nullish coalescing
const country: string = address?.country ?? 'US';

// ✅ Fix with type assertion (if you're sure)
const country: string = address!.country;

// ✅ Fix with conditional
if (address?.country) {
  const country: string = address.country;
  // Use country here
}
Solution 2: Update Type Definitions
npm update @shopify/ui-extensions-react
Solution 3: Fix Interface Definitions
interface Props {
  // ❌ Optional but used as required
  address?: Address;
}

function Component({ address }: Props) {
  // Error: address might be undefined
  console.log(address.country);
}

// ✅ Fix: Make required
interface Props {
  address: Address;
}

// OR handle optional properly
function Component({ address }: Props) {
  if (!address) return null;
  console.log(address.country);
}

Function Issues

Symptoms:
  • Discount/shipping/payment not applying
  • No function logs
  • Function seems inactive
Solution 1: Verify Function is ActiveFor discount functions:
  1. Go to Discounts in Shopify admin
  2. Find your discount
  3. Check status is “Active”
  4. Verify dates are current
  5. Check usage limits not exceeded
Solution 2: Check Function Logs
shopify app function logs --watch
If no logs appear, function isn’t being calledSolution 3: Test Locally
cd extensions/my-function
echo '{"cart":{"lines":[]}}' | cargo run
# or
echo '{"cart":{"lines":[]}}' | node src/run.js
Solution 4: Verify Input QueryCheck run.graphql has required fields:
query RunInput {
  cart {
    lines {
      quantity
      merchandise {
        ... on ProductVariant {
          id
        }
      }
    }
  }
}
Symptoms:
  • Function executes but doesn’t do anything
  • Logs show empty operations
  • Logic seems correct
Solution 1: Add Debug Logging
fn run(input: Input) -> Result<FunctionRunResult> {
    eprintln!("Input: {:?}", input);
    
    let operations = calculate_operations(&input);
    
    eprintln!("Operations: {:?}", operations);
    
    Ok(FunctionRunResult { operations })
}
Solution 2: Check Logic Conditions
// Add logging to see what's failing
let operations = input.cart.lines.iter()
    .filter_map(|line| {
        eprintln!("Processing line: {:?}", line);
        
        if line.quantity < 2 {
            eprintln!("Quantity too low: {}", line.quantity);
            return None;
        }
        
        Some(create_discount(line))
    })
    .collect();

eprintln!("Total operations: {}", operations.len());
Solution 3: Verify Return Value
// ❌ Wrong: Returns empty
Ok(FunctionRunResult {
    operations: vec![],
})

// ✅ Correct: Returns operations
Ok(FunctionRunResult {
    operations: calculated_operations,
})
Symptoms:
  • Function exceeds 5ms limit
  • Execution times out
  • Slow performance
Solution 1: Use Rust Instead of JavaScriptRust is 10-100x faster:
# Convert JS function to Rust
shopify app generate extension --template rust-function
Solution 2: Optimize Loops
// ❌ Slow: Nested loops
for line in &input.cart.lines {
    for other_line in &input.cart.lines {
        // O(n²) - BAD
    }
}

// ✅ Fast: Single pass
let result = input.cart.lines.iter()
    .filter_map(|line| process(line))
    .collect();  // O(n) - GOOD
Solution 3: Cache Calculations
// ❌ Recalculates repeatedly
fn process_lines(lines: &[CartLine]) {
    for line in lines {
        let total = calculate_total(lines);  // BAD
        // ...
    }
}

// ✅ Calculate once
fn process_lines(lines: &[CartLine]) {
    let total = calculate_total(lines);  // GOOD
    for line in lines {
        // Use cached total
    }
}
Solution 4: Reduce Query SurfaceOnly query fields you need:
# ❌ Queries too much data
query RunInput {
  cart {
    lines {
      id
      quantity
      merchandise {
        ... on ProductVariant {
          id
          title
          price
          image { url }
          product {
            id
            title
            description
            tags
            vendor
          }
        }
      }
    }
  }
}

# ✅ Only queries necessary fields
query RunInput {
  cart {
    lines {
      quantity
      merchandise {
        ... on ProductVariant {
          id
        }
      }
    }
  }
}

Deployment Issues

Symptoms:
  • Fly.io build fails
  • Red status in dashboard
  • Deployment doesn’t complete
Solution 1: Check Build Logs
  1. Open Fly.io project
  2. Select service
  3. Click failed deployment
  4. Review build logs for specific error
Solution 2: Fix TypeScript Errors
Error: Type 'string | undefined' is not assignable to type 'string'
Add type guards (see TypeScript section above)Solution 3: Fix Missing Dependencies
Error: Cannot find module '@shopify/ui-extensions-react'
Verify package.json:
{
  "dependencies": {
    "@shopify/ui-extensions-react": "^2024.10.0",
    "react": "^18.0.0"
  }
}
Solution 4: Node Version MismatchSpecify Node version in package.json:
{
  "engines": {
    "node": "20.x"
  }
}
Symptoms:
  • Fly.io shows success
  • Extension doesn’t reflect changes
  • Old version still showing
Solution 1: Hard Refresh Browser
Ctrl+Shift+R (Windows/Linux)
Cmd+Shift+R (Mac)
Solution 2: Clear Shopify Cache
shopify app deploy --force --reset
Solution 3: Check Deployed Version
shopify app versions list
Verify latest version is currentSolution 4: Manually Release
shopify app release --version=latest --force
Symptoms:
  • Cannot push to repository
  • Permission denied error
  • Authentication failed
Solution 1: Regenerate Token
  1. Go to GitHub Settings → Developer settings → Personal access tokens
  2. Delete old token
  3. Create new token with repo and workflow scopes
  4. Update in Synapse settings
Solution 2: Check Repository ExistsVerify repository at:
https://github.com/user-{userId}/synapse-extensions
Solution 3: Check Branch ProtectionIf pushing to main, disable branch protection temporarilySolution 4: Force Push (Careful!)
git push --force origin branch-name
⚠️ Only if you’re sure. This overwrites remote history.

Performance Issues

Symptoms:
  • Extension takes > 1 second to appear
  • Checkout feels sluggish
  • Loading spinner shows too long
Solution 1: Check Bundle Size
npm run build -- --stats
npx webpack-bundle-analyzer dist/stats.json
Target: < 50KBSolution 2: Remove Large Dependencies
// ❌ Remove these if present
"lodash": "^4.17.21",        // 71KB
"moment": "^2.29.4",         // 290KB
"axios": "^1.4.0",           // 31KB

// ✅ Use these instead
// Native methods instead of lodash
// Native Date instead of moment
// Native fetch instead of axios
Solution 3: Lazy Load Components
import { lazy, Suspense } from 'react';

const HeavyComponent = lazy(() => import('./HeavyComponent'));

function Extension() {
  return (
    <Suspense fallback={<SkeletonText />}>
      <HeavyComponent />
    </Suspense>
  );
}
Solution 4: Optimize Re-renders
import { memo } from 'react';

const ExpensiveComponent = memo(({ data }) => {
  // Only re-renders when data changes
  return <div>{/* Complex rendering */}</div>;
});
Symptoms:
  • Browser tab crashes
  • Fly.io out of memory errors
  • Slow performance over time
Solution 1: Fix Memory Leaks
useEffect(() => {
  const interval = setInterval(() => {
    // Do something
  }, 1000);
  
  // ⚠️ Must cleanup!
  return () => clearInterval(interval);
}, []);
Solution 2: Avoid Large Data Structures
// ❌ Stores entire product catalog
const [products, setProducts] = useState([]);

// ✅ Only stores what's needed
const [productIds, setProductIds] = useState([]);
Solution 3: Use Fly.io paid planFree tier has limited memory. Upgrade for more resources.

When to Ask for Help

If you’ve tried the above solutions and still have issues:

Gather Information

Before asking for help, collect:
  • Generation ID
  • Error messages
  • Browser console logs
  • Fly.io build logs
  • Steps to reproduce
  • Expected vs actual behavior

Contact Support

Reach out to:Email: support@synapsebuilder.orgInclude:
  • Detailed description
  • All error messages
  • What you’ve tried
  • Screenshots if helpful

Community Help

Report Bugs

Found a bug in Synapse?GitHub: l3x3d/synapse/issuesInclude minimal reproduction case

Emergency Rollback

If something breaks in production:
1

Identify Last Working Version

git log --oneline
Find the commit hash of last working version
2

Revert to That Version

git checkout <commit-hash>
git push --force origin <branch-name>
This triggers automatic redeployment
3

Verify Fix

Check checkout to ensure issue is resolved
4

Fix Issue

Fix the problem in a new branch, test thoroughly, then merge

Prevention Tips

Avoid issues before they happen:
  • ✅ Test locally before deploying
  • ✅ Review MCP validation output
  • ✅ Write unit tests for critical logic
  • ✅ Monitor Fly.io logs during deployment
  • ✅ Test in dev store before going live
  • ✅ Use TypeScript strict mode
  • ✅ Follow best practices guide
  • ✅ Keep dependencies updated
  • ✅ Document your changes
  • ✅ Use version control properly

Next Steps