theonedev/onedev · error · ExplicitException

Application (client) ID needs to be specified to generate re

Error message

Application (client) ID needs to be specified to generate refresh token

What it means

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.

Source

Thrown at server-plugin/server-plugin-mail-office365/src/main/java/io/onedev/server/plugin/mail/office365/Office365Connector.java:165

		return timeout;
	}

	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}

	private static String getTokenEndpoint(String tenantId) {
		return String.format("https://login.microsoftonline.com/%s/oauth2/v2.0/token", tenantId);
	}

	@SuppressWarnings("unused")
	private static RefreshToken.Callback getRefreshTokenCallback() {
		String tenantId = (String) EditContext.get().getInputValue("tenantId");
		if (tenantId == null)
			throw new ExplicitException("Directory (tenant) ID needs to be specified to generate refresh token");
		String clientId = (String) EditContext.get().getInputValue("clientId");
		if (clientId == null)
			throw new ExplicitException("Application (client) ID needs to be specified to generate refresh token");
		String clientSecret = (String) EditContext.get().getInputValue("clientSecret");
		if (clientSecret == null)
			throw new ExplicitException("Client secret needs to be specified to generate refresh token");

		String userPrincipalName = (String) EditContext.get().getInputValue("userPrincipalName");
		if (userPrincipalName == null)
			throw new ExplicitException("User principal name needs to be specified to generate refresh token");

		Collection<String> scopes = Lists.newArrayList(
				"https://outlook.office.com/SMTP.Send",
				"https://outlook.office.com/IMAP.AccessAsUser.All",
				"offline_access");

		String authorizeEndpoint = String.format(
				"https://login.microsoftonline.com/%s/oauth2/v2.0/authorize", tenantId);
		String tokenEndpoint = getTokenEndpoint(tenantId);

		return new RefreshToken.Callback() {

View on GitHub (pinned to d44925c47c)

Solutions

  1. Enter the Application (client) ID from the Azure app registration Overview page.
  2. Double-check you didn't swap tenant ID and client ID values.
  3. Complete all fields (tenantId, clientId, clientSecret, userPrincipalName) before generating the token.

Example fix

// before
clientId = null;
// after
clientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
Defensive patterns

Strategy: validation

Validate before calling

if (!clientId || clientId.trim() === "") throw new Error("Fill Application (client) ID before generating refresh token");

Try / catch

try {
    generateRefreshToken();
} catch (ExplicitException e) {
    alert("Complete the connector form first: " + e.getMessage());
}

Prevention

When it happens

Trigger: Generating a refresh token with tenant ID set but the 'Application (client) ID' input empty in the Office365 connector form.

Common situations: User pasted tenant ID into the wrong field or skipped client ID; app registration deleted/IDs misplaced; incomplete transcription from Azure portal.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/02807931066edd07. Report an issue: GitHub.