{"record":{"id":"0e5df8dfa8513c8e","repo":"theonedev/onedev","slug":"directory-tenant-id-needs-to-be-specified-to-gen","errorCode":null,"errorMessage":"Directory (tenant) ID needs to be specified to generate refresh token","messagePattern":"Directory \\(tenant\\) ID needs to be specified to generate refresh token","errorType":"exception","errorClass":"ExplicitException","httpStatus":null,"severity":"error","filePath":"server-plugin/server-plugin-mail-office365/src/main/java/io/onedev/server/plugin/mail/office365/Office365Connector.java","lineNumber":162,"sourceCode":"\t@Editable(order=10100, description=\"Specify timeout in seconds when communicating with mail server\")\n\t@Min(value=5, message=\"This value should not be less than 5\")\n\tpublic int getTimeout() {\n\t\treturn timeout;\n\t}\n\n\tpublic void setTimeout(int timeout) {\n\t\tthis.timeout = timeout;\n\t}\n\n\tprivate static String getTokenEndpoint(String tenantId) {\n\t\treturn String.format(\"https://login.microsoftonline.com/%s/oauth2/v2.0/token\", tenantId);\n\t}\n\n\t@SuppressWarnings(\"unused\")\n\tprivate static RefreshToken.Callback getRefreshTokenCallback() {\n\t\tString tenantId = (String) EditContext.get().getInputValue(\"tenantId\");\n\t\tif (tenantId == null)\n\t\t\tthrow new ExplicitException(\"Directory (tenant) ID needs to be specified to generate refresh token\");\n\t\tString clientId = (String) EditContext.get().getInputValue(\"clientId\");\n\t\tif (clientId == null)\n\t\t\tthrow new ExplicitException(\"Application (client) ID needs to be specified to generate refresh token\");\n\t\tString clientSecret = (String) EditContext.get().getInputValue(\"clientSecret\");\n\t\tif (clientSecret == null)\n\t\t\tthrow new ExplicitException(\"Client secret needs to be specified to generate refresh token\");\n\n\t\tString userPrincipalName = (String) EditContext.get().getInputValue(\"userPrincipalName\");\n\t\tif (userPrincipalName == null)\n\t\t\tthrow new ExplicitException(\"User principal name needs to be specified to generate refresh token\");\n\n\t\tCollection<String> scopes = Lists.newArrayList(\n\t\t\t\t\"https://outlook.office.com/SMTP.Send\",\n\t\t\t\t\"https://outlook.office.com/IMAP.AccessAsUser.All\",\n\t\t\t\t\"offline_access\");\n\n\t\tString authorizeEndpoint = String.format(\n\t\t\t\t\"https://login.microsoftonline.com/%s/oauth2/v2.0/authorize\", tenantId);","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-plugin/server-plugin-mail-office365/src/main/java/io/onedev/server/plugin/mail/office365/Office365Connector.java#L144-L180","documentation":"Office365Connector's refresh-token callback reads the tenantId input from the edit form. The Azure AD directory (tenant) ID is required to build the Microsoft OAuth authorize/token endpoints, so a null value raises an ExplicitException.","triggerScenarios":"Clicking the generate-refresh-token action in the Office365 mail connector form while the 'Directory (tenant) ID' input is empty.","commonSituations":"User hasn't created the Azure app registration yet; copied only client ID/secret from Azure portal; confused tenant ID with client ID fields.","solutions":["Copy the Directory (tenant) ID from the Azure Portal app registration 'Overview' page into the form.","If no app registration exists, create one in Azure AD with SMTP.Send / IMAP.AccessAsUser.All / offline_access permissions.","Fill the field before clicking generate refresh token — it cannot be derived automatically."],"exampleFix":"// before\ntenantId = null;\n// after\ntenantId = \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\";","handlingStrategy":"validation","validationCode":"if (!tenantId || tenantId.trim() === \"\") throw new Error(\"Fill Directory (tenant) ID before generating refresh token\");","typeGuard":null,"tryCatchPattern":"try {\n    generateRefreshToken();\n} catch (ExplicitException e) {\n    alert(\"Complete the connector form first: \" + e.getMessage());\n}","preventionTips":["Copy the tenant ID from Azure app registration Overview before configuring.","Don't confuse tenant ID with client ID — they are both GUIDs.","Create the Azure app registration first, then configure the connector."],"tags":["office365","azure-ad","oauth","validation"],"backgroundTag":"missing-required-config-field","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}