Troubleshooting
Widget Issues
Widget doesn't appear
- Check your app ID – Ensure
NEXT_PUBLIC_YAK_APP_IDor equivalent is set correctly (find your app ID) - Verify YakWidget is inside YakProvider – The widget must be a child of the provider
- 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)
- 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 - 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
- Check API endpoints – Verify your GET and POST handlers return correct responses
- Check network tab – Look for failed requests to
/api/yakor your config/tools endpoints - Verify CORS – If using separate origins, ensure CORS is configured
Styles are broken
- Check CSS loading – Ensure Tailwind/CSS is loaded in your layout
- Check z-index conflicts – The widget uses high z-index values; ensure nothing is covering it
- Theme configuration – Verify your theme prop is correctly structured
API Handler Issues
404 on config/tools endpoints
- Check route path – Ensure the route file matches your endpoint
- Next.js:
app/api/yak/[[...yak]]/route.ts - Remix:
app/routes/api.yak.ts
- Next.js:
- Check export names – Handlers must export
GETandPOST - Verify the path in client – Match
getConfigandonToolCallendpoints
GET returns empty routes
- Check route sources – Verify your route array or sources are populated
- For Next.js auto-scan – Ensure
appDirpath is correct - Check route filter – Your include/exclude patterns may filter everything
POST returns tool errors
- Check tool name – Tool names are case-sensitive
- Verify tool is in manifest – Confirm the tool appears in GET response
- Check input validation – Ensure args match the tool's input schema
- Review executor logs – Add logging to your
executeToolfunction
tRPC Adapter Issues
Procedures not appearing
- Check allowedProcedures – If using
allowedProcedures, procedure must be in the whitelist - Check disallowedProcedures – If using
disallowedProcedures, ensure procedure is not blocked - Verify procedure path – Use the full path (e.g.,
orders.list, not justlist) - Check router exports – Ensure procedures are exported from your router
Context errors
- Verify createContext – Ensure it returns the expected shape
- Check authentication – If procedures require auth, verify it's passed correctly
- 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
- Verify provider –
useYakmust be called insideYakProvider - Check timing – Prompts are queued if called before iframe is ready
- Verify widget state – Check
isOpento see current state
Navigation doesn't work
- Provide onRedirect – Without it, navigation falls back to
window.location.href - Use correct router – Pass your router's navigate function
- 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
- Use lazy loading – Consider
client:idlein Astro or dynamic imports - Check config endpoint – Ensure GET handler responds quickly
- Minimize route/tool count – Large manifests slow down processing
Tool calls are slow
- Add caching – Cache expensive operations where appropriate
- Batch requests – Combine multiple database queries
- 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
apiSecretbut 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 only —
HMAC-SHA256(apiSecret, userId), hex-encoded. - Confirm the
idyou sign on the server is byte-for-byte theidyou 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.