theonedev/onedev · error · ExplicitException

Name already used by another access token of the owner

Error message

Name already used by another access token of the owner

What it means

createToken throws ExplicitException when the requested token name is already used by another access token belonging to the same owner. Token names must be unique per owner, enforced via accessTokenService.findByOwnerAndName().

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/AccessTokenResource.java:79

	@GET
	public Collection<AccessTokenAuthorization> getAuthorizations(@PathParam("accessTokenId") Long accessTokenId) {
		var accessToken = accessTokenService.load(accessTokenId);
		if (!isAdministrator() && !accessToken.getOwner().equals(getAuthUser()))
			throw new UnauthorizedException();
		return accessToken.getAuthorizations();
	}
	
	@Api(order=200, description="Create access token")
	@POST
	public Long createToken(@NotNull @Valid AccessToken accessToken) {
		var owner = accessToken.getOwner();
		if (!isAdministrator() && !owner.equals(getAuthUser()))
			throw new UnauthorizedException();
		else if (owner.isDisabled())
			throw new ExplicitException("Cannot create access token for disabled user");
		
		if (accessTokenService.findByOwnerAndName(owner, accessToken.getName()) != null)
			throw new ExplicitException("Name already used by another access token of the owner");
			
		accessTokenService.createOrUpdate(accessToken);

		if (!getAuthUser().equals(owner)) {
			var newAuditContent = VersionedXmlDoc.fromBean(accessToken.getFacade()).toXML();
			auditService.audit(null, "created access token \"" + accessToken.getName() + "\" in account \"" + owner.getName() + "\" via RESTful API", 
					null, newAuditContent);
		}

		return accessToken.getId();
	}

	@Api(order=250, description="Update access token")
	@Path("/{accessTokenId}")
	@POST
	public Response updateToken(@PathParam("accessTokenId") Long accessTokenId, @NotNull @Valid AccessToken accessToken) {
		var owner = accessToken.getOwner();
		if (!isAdministrator() && !owner.equals(getAuthUser()))

View on GitHub (pinned to d44925c47c)

Solutions

  1. Pick a different, unique token name for that owner.
  2. Delete or rename the existing token with the same name first, then retry.
  3. Generate names programmatically (e.g., include a timestamp) in automation scripts.
  4. Check the existing token list for the owner before creating.

Example fix

// before
{"name": "ci-token", ...}  // 'ci-token' already exists for this owner
// after
{"name": "ci-token-2026-09", ...}
Defensive patterns

Strategy: validation

Validate before calling

const existing = await listOwnerTokens(ownerName);
if (existing.some(t => t.name === desiredName)) {
  throw new Error(`Token name '${desiredName}' already used for owner ${ownerName}`);
}

Type guard

function nameIsFree(existingNames: string[], name: string): boolean {
  return !existingNames.includes(name);
}

Try / catch

try {
  await createToken(payload);
} catch (e) {
  if (/Name already used/.test(String(e.response?.data?.message ?? e.message))) {
    payload.name = `${payload.name}-${Date.now()}`;
    await createToken(payload);
  } else throw e;
}

Prevention

When it happens

Trigger: POST /~access-tokens (AccessTokenResource.createToken) where findByOwnerAndName(owner, accessToken.getName()) returns non-null — a token with the same name already exists for that owner.

Common situations: Re-running idempotent provisioning scripts without unique names; re-creating a token after deletion failed or used a different owner; users unaware of an existing token with the same name created earlier.

Related errors


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