{"record":{"id":"02807931066edd07","repo":"theonedev/onedev","slug":"application-client-id-needs-to-be-specified-to-g","errorCode":null,"errorMessage":"Application (client) ID needs to be specified to generate refresh token","messagePattern":"Application \\(client\\) 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":165,"sourceCode":"\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);\n\t\tString tokenEndpoint = getTokenEndpoint(tenantId);\n\n\t\treturn new RefreshToken.Callback() {","sourceCodeStart":147,"sourceCodeEnd":183,"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#L147-L183","documentation":"Office365Connector's refresh-token callback validates the clientId input after tenantId. The Application (client) ID of the Azure app registration is required to start the OAuth flow; a null value throws an ExplicitException.","triggerScenarios":"Generating a refresh token with tenant ID set but the 'Application (client) ID' input empty in the Office365 connector form.","commonSituations":"User pasted tenant ID into the wrong field or skipped client ID; app registration deleted/IDs misplaced; incomplete transcription from Azure portal.","solutions":["Enter the Application (client) ID from the Azure app registration Overview page.","Double-check you didn't swap tenant ID and client ID values.","Complete all fields (tenantId, clientId, clientSecret, userPrincipalName) before generating the token."],"exampleFix":"// before\nclientId = null;\n// after\nclientId = \"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\";","handlingStrategy":"validation","validationCode":"if (!clientId || clientId.trim() === \"\") throw new Error(\"Fill Application (client) 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":["Paste client ID and tenant ID from the same app registration Overview page.","Verify field placement when copying GUIDs from Azure Portal.","Fill tenantId, clientId, clientSecret, userPrincipalName together."],"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"}