Troubleshooting first-time setup
Common issues encountered during initial tenant setup, with the exact fix for each. If you hit something not on this list, search this repo's docs/ or contact your operator.
SSO
AADSTS50011: The redirect URI '...' specified in the request does not match the redirect URIs configured for the application
Cause: the redirect URI EnClaw sent to Azure AD doesn't match anything in the app registration's allowed list.
Fix: Entra admin → App registrations → find the app by client ID (shown in the error message) → Authentication → Web → Redirect URIs → add the exact URL from the error. Save.
If you're a platform operator running multiple SaaS environments against the same app, register all four callback URLs at once:
https://your-org-api.enclaw.com/api/auth/sso/callback
https://app-api.enclaw.com/api/auth/sso/callback
https://stage-app-api.enclaw.com/api/auth/sso/callback
https://dev-app-api.enclaw.com/api/auth/sso/callback
AADSTS65001: The user or administrator has not consented to use the application
Cause: Application permissions (not delegated) were added but admin consent wasn't granted.
Fix: Entra admin → App registrations → your app → API permissions → click ✓ Grant admin consent for [Tenant]. The lock icon next to each Application permission should turn into a green check.
AADSTS700016: Application with identifier 'xxx' was not found in the directory
Cause: the client ID in the EnClaw SSO config doesn't exist in the Azure AD tenant.
Fix: double-check the client ID — easy typo target. It's the Application (client) ID on the app registration's Overview page, not the Object ID.
"Sign in with [provider]" button never appears on /login
Cause: the SSO config row in /sso-providers isn't marked active, OR the email you typed doesn't match the SSO config's email-domain rule (if you've set one).
Fix: /sso-providers → edit the row → tick Is active. If you've set an explicit email-domain allowlist, make sure your email matches.
After SSO sign-in, the URL bar lands on /login?error=...
Cause: the SSO callback received a valid token from the IdP but the EnClaw side rejected it. Reasons vary — most common is auto-provision is off and the user doesn't exist locally yet.
Fix: check the error text in the query string (URL-decoded). If it's "User not found", either invite the user first or enable auto-provision in your SSO config.
Invites
"Join undefined" button and the tenant name is missing
Cause: old API version returning the wrong response shape ({tenant: {...}} instead of flat tenantName).
Fix: redeploy your environment — fix landed in the invites service. If you've redeployed and still see this, your CDN may be caching the JS bundle. Hard-refresh (Ctrl+Shift+R).
"Forbidden resource" 403 when creating an invite
Cause: the operator UI's /admin/saas/tenants/[id]/invites route used to gate strictly on platform_admin, rejecting super_admin actors.
Fix: redeploy — both roles now pass the guard. If you can't redeploy, switch your account to platform_admin instead of super_admin (same effective privileges in SaaS mode).
"New user invites require password + name. Send them in body" error
Cause: the previewInvite endpoint wasn't returning isNewUser, so the UI sent a bare-token accept body, but the server treated the email as new and required password+name.
Fix: redeploy. If you can't redeploy, you can work around manually by hitting POST /api/invites/accept with { token, name: "First Last", password: "Something1!" } via curl/Postman.
Invite shows red "No email provider configured" banner
Cause: no active Teams channel integration with the send_email allowed action.
Fix: /integrations → Microsoft Teams — connect it, tick Send emails from EnClaw inbox under Allowed Actions, set Outlook Send-From Email, save. Subsequent invites will show the green "Email sent" banner.
In the meantime, the invite is still valid — copy the link from the dialog and share it manually.
Invite link recipient sees "Invalid invite" or "Invite expired"
Cause: the rawToken in the URL is wrong (truncated, transcription error) OR the invite genuinely expired (default 7 days).
Fix: reissue from /users → Invites → click the row's Reissue button. The old link is revoked, a fresh token + URL is generated. The new email goes out via the same path.
CORS / network
Browser DevTools shows CORS error: access-control-allow-origin doesn't match
Cause: the API was deployed without the custom-domain set, so it accepts CORS only from the default ACA FQDN. Browser at <env-prefix>app.enclaw.com gets blocked.
Fix: your operator needs to redeploy with customWebDomain passed to Bicep. Operator-side commits landed in late May 2026; if your deployment predates that, ask the operator to redeploy.
Login form POSTs to http://localhost:3001/api/auth/login
Cause: the web Docker image was built without NEXT_PUBLIC_API_URL baked in. Next.js bakes NEXT_PUBLIC_* env vars at build time, not runtime.
Fix: operator-side issue. The build job must pass --build-arg NEXT_PUBLIC_API_URL=https://<your-api-host>/api. Fix landed late May 2026.
Cannot GET /health returning 404 — is the API alive?
Yes, that 404 means the API is responding. The endpoint just isn't /health — try /api/healthz or visit /api/auth/login-options (POST) to confirm. A real "API is down" symptom is timeout or "connection refused", not a 404.
LLM providers
Test button on the provider row shows red "auth failed"
Cause: API key is wrong, expired, or out of region.
Fix: rotate the key in the provider's console, paste fresh, save. For Azure OpenAI: confirm the endpoint URL is for the region your deployment is in.
Models picker on the agent edit page is empty
Cause: the provider returned no models. Usually a permission issue — your API key doesn't have access to any model deployments.
Fix: check the provider console — is at least one model deployed / accessible? For Azure OpenAI: deploy a model in your Azure resource first.
Connectors (My Connections)
Connecting Outlook prompts "Need admin approval" for non-admin users
A non-admin clicks Connect on the Outlook connector in My Connections and Microsoft shows a "Need admin approval — EnClaw needs permission to access resources in your organization that only an admin can grant" page instead of the normal consent screen. The connection never completes.
Cause: two things have to both be true, and usually one is missing.
- The tenant restricts user consent (the common default), so a non-admin can never self-consent to the app — Entra converts the consent screen into "Need admin approval". This is fixed once, org-wide, by an admin granting consent for the app.
- The connect flow was sending
prompt=consenton every authorization. That forces Entra to re-run the full consent ceremony every time and ignores the admin consent grant — so even after an admin consents, non-admins still hit the wall. Fixed in code by usingprompt=select_account(seeapps/api/src/modules/integrations/integrations.controller.ts,startMicrosoftOAuth).
Fix:
- Grant admin consent on the app registration — not the Enterprise application blade. The Enterprise application → Permissions page shows status only and bounces you with "To configure requested permissions for apps you own, use the app registration." Go to Entra admin → App registrations → EnClaw → API permissions → click ✓ Grant admin consent for [Tenant]. Every permission row should flip to a green "Granted for [Tenant]". The connector reuses the shared Teams app registration (the
teamsAppIdon theteamschannel_integrationsrow), so this single grant covers all users. - Confirm the delegated scopes are registered. The connect flow requests these delegated Microsoft Graph scopes (built from the connector's allowed actions in
startMicrosoftOAuth):openid,profile,email,offline_access,Mail.Read,Mail.ReadWrite,Mail.Send,Calendars.Read,Calendars.ReadWrite,Tasks.Read,Tasks.ReadWrite,Notes.Create,Notes.Read,Notes.ReadWrite,Files.Read,Files.ReadWrite. If a user enables an action whose scope isn't on the app registration, that connection re-prompts even after admin consent — add the missing delegated permission, then re-grant consent. - Ensure
prompt=consentis not being sent. The start endpoint must useprompt=select_account(or omitprompt).prompt=consentre-triggers consent on every connect and defeats the admin grant. - Have the user retry My Connections → Connect Outlook. They should now get an account picker and the connection completes silently.
Granting admin consent on this app consents the entire permission set at once, including broad application permissions (
Group.ReadWrite.All,User.Read.All,Sites.Manage.All,Chat.ReadWrite.All,Mail.Sendas-any-user, etc.). That is expected for the shared Teams/bot/SSO app registration, but confirm the app legitimately needs all of it before clicking.
When to escalate to EnClaw support
- The error mentions an internal-sounding identifier (
AADSTS,tenant_id,agent_id) and the fixes above don't apply. - The web app loads but the dashboard is empty and DevTools shows persistent 500s from the API.
- You hit a
Provider rejected the messagebanner on every invite even after fixing the Teamssend_emailtoggle.
Have the timestamp, request ID (DevTools → Network → the failing request → Response headers → x-request-id), and your tenant ID ready when you contact support — it dramatically speeds up diagnosis.