{"record":{"id":"97fac30f53482f68","repo":"theonedev/onedev","slug":"client-secret-needs-to-be-specified-to-generate-re-97fac3","errorCode":null,"errorMessage":"Client secret needs to be specified to generate refresh token","messagePattern":"Client secret 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":168,"sourceCode":"\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() {\n\n\t\t\t@Override\n\t\t\tpublic String getAuthorizeEndpoint() {","sourceCodeStart":150,"sourceCodeEnd":186,"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#L150-L186","documentation":"Office365Connector's refresh-token callback next validates the clientSecret input. The Microsoft OAuth authorization-code flow requires the app's client secret credential, so a null value raises an ExplicitException.","triggerScenarios":"Generating a refresh token with tenantId and clientId filled but the 'Client secret' input empty in the Office365 connector form.","commonSituations":"Azure app has no client secret created under 'Certificates & secrets'; secret expired and was cleared; user thinks only public-client flow (no secret) is used.","solutions":["Create a new client secret in Azure Portal (App registration -> Certificates & secrets) and paste it into the form.","Check the existing secret's expiry and regenerate if expired.","Complete all connector fields before clicking generate refresh token."],"exampleFix":"// before\nclientSecret = null;\n// after\nclientSecret = \"abc123~xxxxxxxxxxxxxxxxxxxxx\";","handlingStrategy":"validation","validationCode":"if (!clientSecret || clientSecret.trim() === \"\") throw new Error(\"Fill Client secret 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":["Create a client secret under Certificates & secrets in Azure before configuring.","Track secret expiry and rotate before it lapses.","Fill all app credential fields before clicking generate."],"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-14T05:17:10.506Z"}