{"record":{"id":"883767d2e2a4a34c","repo":"Mintplex-Labs/anything-llm","slug":"client-id-and-client-secret-are-required","errorCode":null,"errorMessage":"Client ID and Client Secret are required.","messagePattern":"Client ID and Client Secret are required\\.","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"server/endpoints/utils/outlookAgentUtils.js","lineNumber":29,"sourceCode":" */\nfunction getOutlookRedirectUri(request) {\n  const protocol = request.headers[\"x-forwarded-proto\"] || request.protocol;\n  const host = request.headers[\"x-forwarded-host\"] || request.get(\"host\");\n  return `${protocol}://${host}/api/agent-skills/outlook/auth-callback`;\n}\n\nfunction outlookAgentEndpoints(app) {\n  if (!app) return;\n\n  app.post(\n    \"/admin/agent-skills/outlook/auth-url\",\n    [validatedRequest, isSingleUserMode],\n    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        }","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/endpoints/utils/outlookAgentUtils.js#L11-L47","documentation":"The 400 reply from POST /admin/agent-skills/outlook/auth-url when the Azure app registration credentials are incomplete. The handler needs both clientId and clientSecret from the request body to build the Microsoft OAuth URL; if either is missing/falsy the call is rejected before the Outlook library is touched.","triggerScenarios":"POST /admin/agent-skills/outlook/auth-url with only clientId, only clientSecret, an empty body, or mis-keyed fields (client_id). The values must come from an Azure AD app registration exposing the Outlook scopes with a web redirect URI.","commonSituations":"Admin saves the form before pasting the secret; secret copied with quotes/whitespace making it empty after a UI bug; Azure app not yet created so only one value is available; integration sends the tenantId but forgets the secret.","solutions":["Create/register an Azure AD app, then send both {\"clientId\": \"...\", \"clientSecret\": \"...\"} with Content-Type: application/json.","Double-check key names - camelCase clientId/clientSecret, not snake_case.","If authType is 'organization', also include tenantId to avoid the follow-up 400 at the next check."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function outlookAuthUrl({ clientId, clientSecret, tenantId, authType }) {\n  if (!clientId?.trim() || !clientSecret?.trim()) throw new Error(\"clientId and clientSecret are both required\");\n  if (authType === \"organization\" && !tenantId?.trim()) throw new Error(\"tenantId is required for organization auth\");\n  return fetch(\"/api/admin/agent-skills/outlook/auth-url\", {\n    method: \"POST\", headers: { \"Content-Type\": \"application/json\" },\n    body: JSON.stringify({ clientId: clientId.trim(), clientSecret: clientSecret.trim(), tenantId: tenantId?.trim() || \"\", authType }),\n  });\n}","typeGuard":"const hasOutlookCredentials = (b) =>\n  typeof b?.clientId === \"string\" && b.clientId.trim() !== \"\" &&\n  typeof b?.clientSecret === \"string\" && b.clientSecret.trim() !== \"\";","tryCatchPattern":null,"preventionTips":["Disable the submit action until both credential fields are non-empty.","Register the Azure app first; the form needs real clientId/clientSecret from Entra ID.","Send tenantId whenever you select organization auth to satisfy the next validation too."],"tags":["outlook","oauth","azure-ad","validation","missing-parameter"],"backgroundTag":"missing-oauth-credentials","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}