{"record":{"id":"9eaef81b8d2412d6","repo":"Mintplex-Labs/anything-llm","slug":"result-error","errorCode":null,"errorMessage":"${result.error}","messagePattern":"\\$\\{result\\.error\\}","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"server/endpoints/utils/outlookAgentUtils.js","lineNumber":77,"sourceCode":"\n        // If auth type changed, clear tokens as they won't work with different authority\n        if (\n          existingConfig.authType &&\n          existingConfig.authType !== validAuthType\n        ) {\n          delete configUpdate.accessToken;\n          delete configUpdate.refreshToken;\n          delete configUpdate.tokenExpiry;\n        }\n\n        await outlookLib.OutlookBridge.updateConfig(configUpdate);\n        outlookLib.reset();\n\n        const redirectUri = getOutlookRedirectUri(request);\n        const result = await outlookLib.getAuthUrl(redirectUri);\n        if (!result.success) {\n          return response\n            .status(400)\n            .json({ success: false, error: result.error });\n        }\n\n        return response.status(200).json({ success: true, url: result.url });\n      } catch (e) {\n        console.error(\"Outlook auth URL error:\", e);\n        response.status(500).json({ success: false, error: e.message });\n      }\n    }\n  );\n\n  app.get(\n    \"/agent-skills/outlook/auth-callback\",\n    [validatedRequest, isSingleUserMode],\n    async (request, response) => {\n      try {\n        const { code, error, error_description } = request.query;\n","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/server/endpoints/utils/outlookAgentUtils.js#L59-L95","documentation":"The 400 reply from POST /admin/agent-skills/outlook/auth-url when outlookLib.getAuthUrl(redirectUri) reports failure. getAuthUrl re-reads the saved Outlook config and fails when clientId is empty (config incomplete) or validateOrganizationAuth() rejects it (organization authType without tenantId). Because the endpoint just wrote clientId into the config, seeing this usually means the saved value ended up empty (e.g. clientId was whitespace that trimmed to '') or the persisted authType/tenantId combination is inconsistent.","triggerScenarios":"clientId passed as whitespace/quotes trimming to an empty string; the config update persisted authType 'organization' with an empty tenantId; a stale or concurrently overwritten outlook_agent_config row between updateConfig and getConfig; redirect URI not registered in the Azure app (fails later in the browser flow rather than here).","commonSituations":"Quoted secret/id copied from a password manager; two admins saving conflicting Outlook configs; config row left half-written after a previous failed save; organization tenant toggled in the UI without re-entering the tenant.","solutions":["Re-send clientId as a clean, non-empty string (no surrounding quotes) and include tenantId when using organization auth, then retry.","GET the Outlook status endpoint to confirm the persisted config (clientId present, authType/tenantId consistent) before requesting the auth URL.","If the stored config is scrambled, revoke (POST /admin/agent-skills/outlook/revoke) and re-configure from scratch."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Confirm persisted config is complete before requesting the auth URL\nconst status = await (await fetch(\"/api/agent-skills/outlook/status\")).json();\nif (!status.hasCredentials) throw new Error(\"Save clientId/clientSecret first\");\nif (status.config?.authType === \"organizations\" && !status.config?.tenantId) throw new Error(\"tenantId required for organization auth\");\nconst { url } = await (await fetch(\"/api/admin/agent-skills/outlook/auth-url\", { method: \"POST\", headers, body })).json();","typeGuard":"const outlookConfigComplete = (cfg) =>\n  !!cfg?.clientId?.trim() &&\n  (cfg.authType !== \"organizations\" || !!cfg.tenantId?.trim());","tryCatchPattern":null,"preventionTips":["Trim credentials client-side so whitespace-only values never reach the server.","Check the status endpoint after saving config and before generating the OAuth URL.","If config state gets inconsistent, revoke and re-configure rather than patching around it."],"tags":["outlook","oauth","configuration","azure-ad"],"backgroundTag":"oauth-misconfiguration","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}