Yak Docs

Troubleshooting

Widget Issues

Widget doesn't appear

  1. Check your app ID – Ensure NEXT_PUBLIC_YAK_APP_ID or equivalent is set correctly (find your app ID)
  2. Verify YakWidget is inside YakProvider – The widget must be a child of the provider
  3. Check your domain is allowed – If the widget renders but shows "This chatbot is not authorized to run on this domain", add the origin to your allowlist (Allowed Origins)
  4. On Vue, Svelte, Angular, or Nuxt: pass trigger: true – These SDKs don't render a launcher by default, so the widget mounts with no button to open it
  5. Check for JavaScript errors – Open browser console for any errors
// ✓ Correct
<YakProvider appId="your-app-id" {...props}>
  <YakWidget />
</YakProvider>

// ✗ Wrong - widget outside provider
<YakProvider appId="your-app-id" {...props}>
  {children}
</YakProvider>
<YakWidget />

Widget loads but doesn't respond

  1. Check API endpoints – Verify your GET and POST handlers return correct responses
  2. Check network tab – Look for failed requests to /api/yak or your config/tools endpoints
  3. Verify CORS – If using separate origins, ensure CORS is configured

Styles are broken

  1. Check CSS loading – Ensure Tailwind/CSS is loaded in your layout
  2. Check z-index conflicts – The widget uses high z-index values; ensure nothing is covering it
  3. Theme configuration – Verify your theme prop is correctly structured

API Handler Issues

404 on config/tools endpoints

  1. Check route path – Ensure the route file matches your endpoint
    • Next.js: app/api/yak/[[...yak]]/route.ts
    • Remix: app/routes/api.yak.ts
  2. Check export names – Handlers must export GET and POST
  3. Verify the path in client – Match getConfig and onToolCall endpoints

GET returns empty routes

  1. Check route sources – Verify your route array or sources are populated
  2. For Next.js auto-scan – Ensure appDir path is correct
  3. Check route filter – Your include/exclude patterns may filter everything

POST returns tool errors

  1. Check tool name – Tool names are case-sensitive
  2. Verify tool is in manifest – Confirm the tool appears in GET response
  3. Check input validation – Ensure args match the tool's input schema
  4. Review executor logs – Add logging to your executeTool function

tRPC Adapter Issues

Procedures not appearing

  1. Check allowedProcedures – If using allowedProcedures, procedure must be in the whitelist
  2. Check disallowedProcedures – If using disallowedProcedures, ensure procedure is not blocked
  3. Verify procedure path – Use the full path (e.g., orders.list, not just list)
  4. Check router exports – Ensure procedures are exported from your router

Context errors

  1. Verify createContext – Ensure it returns the expected shape
  2. Check authentication – If procedures require auth, verify it's passed correctly
  3. Review tRPC errors – Check server logs for validation or context errors
// Ensure your context factory handles missing request
createContext: async (opts) => {
  // opts.req may be undefined in some contexts
  return createContext(opts?.req);
}

Programmatic API Issues

openWithPrompt doesn't work

  1. Verify provideruseYak must be called inside YakProvider
  2. Check timing – Prompts are queued if called before iframe is ready
  3. Verify widget state – Check isOpen to see current state
  1. Provide onRedirect – Without it, navigation falls back to window.location.href
  2. Use correct router – Pass your router's navigate function
  3. Check path format – Paths should start with /
// React Router
<YakProvider onRedirect={(path) => navigate(path)} />

// Next.js
const router = useRouter();
<YakProvider onRedirect={(path) => router.push(path)} />

Performance Issues

Widget is slow to load

  1. Use lazy loading – Consider client:idle in Astro or dynamic imports
  2. Check config endpoint – Ensure GET handler responds quickly
  3. Minimize route/tool count – Large manifests slow down processing

Tool calls are slow

  1. Add caching – Cache expensive operations where appropriate
  2. Batch requests – Combine multiple database queries
  3. Check N+1 patterns – Avoid fetching related data in loops

Module Format Issues (ESM & CommonJS)

Every @yak-io/* package ships both ESM and CommonJS builds. Modern bundlers (Vite, webpack, Next.js, Rollup, esbuild) and native ESM in Node pick the ESM build automatically; CommonJS require() and most Jest setups pick the CommonJS build via the package's require export condition (and its main field, for older tooling). You don't need any special configuration.

SyntaxError: Unexpected token 'export' in Jest

This means the test runner loaded the ESM build and tried to parse it as CommonJS. With current Yak SDKs Jest 28+ resolves the CommonJS build on its own, so this should no longer happen. If you still hit it on an older Jest or a custom resolver that forces the import condition, allow Yak's packages through Jest's transform:

// jest.config.js
module.exports = {
  transformIgnorePatterns: ["node_modules/(?!(@yak-io)/)"],
};

ERR_REQUIRE_ESM when calling require("@yak-io/...")

Current SDKs ship CommonJS, so a plain require() works. If you see this error you're almost certainly on an old, ESM-only version — upgrade to the latest @yak-io/* release.

Common Error Messages

"Unknown tool: xxx"

The tool name in the POST request doesn't match any defined tool.

  • Check tool names in your manifest
  • Verify the correct adapter is handling the call

"Invalid user hash"

The signed end-user identity didn't verify. Unlike session errors, the widget does not recover from this on its own — the user stays broken until the hash is right.

  • Most common cause: you rotated apiSecret but haven't redeployed. Every hash signed with the old secret is now invalid. Redeploy your server with the new secret.
  • Confirm you're signing the user id onlyHMAC-SHA256(apiSecret, userId), hex-encoded.
  • Confirm the id you sign on the server is byte-for-byte the id you pass to the provider.

"Origin not allowed for this application"

The page's origin isn't in the app's allowlist. Add it under Allowed Origins. In the widget this surfaces as "This chatbot is not authorized to run on this domain."

Session token errors

"Invalid session token", "Session token expired", and "Session token revoked" are recoverable — the SDK silently mints a fresh token and retries, so users shouldn't see them. Seeing them repeatedly in logs is normal after a sign-out-all-sessions.

"Session identity mismatch" means a token bound to one end-user was presented for another. The SDK rotates the token automatically when the user prop changes; if you see this, check you aren't sharing one token across users (for example by caching it server-side).

"Failed to fetch config"

The GET endpoint is unreachable.

  • Check the endpoint URL in getConfig
  • Verify the server is running
  • Check for CORS issues

Still stuck? Check the browser console and server logs for more detailed error messages.

On this page