{"record":{"id":"1143ea6216a34258","repo":"Mintplex-Labs/anything-llm","slug":"tenant-id-is-required-for-organization-only-authen","errorCode":null,"errorMessage":"Tenant ID is required for organization-only authentication.","messagePattern":"Tenant ID is required for organization-only authentication\\.","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"server/endpoints/utils/outlookAgentUtils.js","lineNumber":42,"sourceCode":"    async (request, response) => {\n      try {\n        const { clientId, tenantId, clientSecret, authType } = reqBody(request);\n\n        if (!clientId || !clientSecret) {\n          return response.status(400).json({\n            success: false,\n            error: \"Client ID and Client Secret are required.\",\n          });\n        }\n\n        const outlookLib = require(\"../../utils/agents/aibitat/plugins/outlook/lib\");\n        const { AUTH_TYPES } = outlookLib;\n        const validAuthType = Object.values(AUTH_TYPES).includes(authType)\n          ? authType\n          : AUTH_TYPES.common;\n\n        if (validAuthType === AUTH_TYPES.organization && !tenantId) {\n          return response.status(400).json({\n            success: false,\n            error:\n              \"Tenant ID is required for organization-only authentication.\",\n          });\n        }\n\n        const existingConfig = await outlookLib.OutlookBridge.getConfig();\n        const configUpdate = {\n          ...existingConfig,\n          clientId: clientId.trim(),\n          tenantId: tenantId?.trim() || \"\",\n          authType: validAuthType,\n        };\n\n        if (!/^\\*+$/.test(clientSecret))\n          configUpdate.clientSecret = clientSecret.trim();\n\n        // If auth type changed, clear tokens as they won't work with different authority","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/endpoints/utils/outlookAgentUtils.js#L24-L60","documentation":"The 400 reply from POST /admin/agent-skills/outlook/auth-url when the resolved authType is AUTH_TYPES.organization but no tenantId was supplied. Organization-only auth builds the Microsoft authority URL from the specific tenant, so a tenant id is mandatory; for 'common' auth it is optional. authType defaults to common when the value is not one of the known AUTH_TYPES.","triggerScenarios":"POST /admin/agent-skills/outlook/auth-url with {\"authType\": \"organization\"} (and valid clientId/clientSecret) but no tenantId, an empty tenantId, or a tenantId key mismatch (tenant_id).","commonSituations":"Admin switches the app to single-tenant in Azure but forgets the tenant field in the integration; copying the tenant GUID with quotes that trim to empty; using the tenant name where the GUID is expected downstream.","solutions":["Include {\"tenantId\": \"<azure tenant guid>\"} in the auth-url request when authType is 'organization'.","Find the tenant id in Azure portal - Microsoft Entra ID > Overview > Tenant ID.","If you actually want consumer/personal accounts too, send authType 'common' (or omit it) so tenantId is not required."],"exampleFix":"// before\n{ \"clientId\": \"...\", \"clientSecret\": \"...\", \"authType\": \"organization\" }\n\n// after\n{ \"clientId\": \"...\", \"clientSecret\": \"...\", \"authType\": \"organization\", \"tenantId\": \"<tenant-guid>\" }","handlingStrategy":"validation","validationCode":"const AUTH_TYPES = { common: \"common\", organization: \"organizations\" };\nfunction validateOutlookAuthBody(body) {\n  if (!body.clientId?.trim() || !body.clientSecret?.trim()) throw new Error(\"Client ID and Client Secret are required.\");\n  const authType = Object.values(AUTH_TYPES).includes(body.authType) ? body.authType : AUTH_TYPES.common;\n  if (authType === AUTH_TYPES.organization && !body.tenantId?.trim()) throw new Error(\"Tenant ID is required for organization-only authentication.\");\n  return { ...body, authType };\n}","typeGuard":"const needsTenantId = (authType) => authType === \"organizations\";","tryCatchPattern":null,"preventionTips":["Make the tenant field required in the UI when single-tenant auth is selected.","Store the Entra tenant GUID in your app config once and reuse it.","Prefer 'common' auth unless the app is deliberately single-tenant."],"tags":["outlook","oauth","azure-ad","validation","tenant"],"backgroundTag":"missing-oauth-credentials","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}