theonedev/onedev · error · NotAcceptableException

Invalid access token

Error message

Invalid access token

What it means

After locating the project, triggerJob looks up the supplied access token via accessTokenService.findByValue. If no token matches, NotAcceptableException (406) 'Invalid access token' is thrown. The endpoint relies on an explicit 'access_token' query parameter rather than HTTP auth.

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/TriggerJobResource.java:106

    public Long triggerJobViaPost(
    		@Api(description="Path of the project") @QueryParam(PARAM_PROJECT) @NotEmpty String projectPath, 
    		@Api(description=REF_DESCRIPTION) @QueryParam(PARAM_BRANCH) @Nullable String branch, 
    		@Api(description=REF_DESCRIPTION) @QueryParam(PARAM_TAG) @Nullable String tag, 
    		@QueryParam(PARAM_JOB) @NotEmpty String job,
			@Api(description=ACCESS_TOKEN_DESCRIPTION) @QueryParam(PARAM_ACCESS_TOKEN) @NotEmpty String accessToken, 
    		@Context UriInfo uriInfo) {
		return triggerJob(projectPath, branch, tag, job, accessToken, uriInfo);
    }

    private Long triggerJob(String projectPath, @Nullable String branch, @Nullable String tag, String job,
							String accessTokenValue, UriInfo uriInfo) {
		Project project = projectService.findByPath(projectPath);
		if (project == null)
			throw new NotAcceptableException("Project not found: " + projectPath);

		var accessToken = accessTokenService.findByValue(accessTokenValue);
		if (accessToken == null)
			throw new NotAcceptableException("Invalid access token");
		
		var subject = accessToken.asSubject();
		var user = SecurityUtils.getUser(subject);
		ThreadContext.bind(subject);
		try {
			if (!SecurityUtils.canRunJob(subject, project, job))		
				throw new UnauthorizedException();

			if (StringUtils.isNotBlank(branch) && StringUtils.isNotBlank(tag)) 
				throw new NotAcceptableException("Either branch or tag should be specified, but not both");
			
			String refName;
			if (branch != null)
				refName = GitUtils.branch2ref(branch);
			else if (tag != null)
				refName = GitUtils.tag2ref(tag);
			else
				refName = GitUtils.branch2ref(project.getDefaultBranch());

View on GitHub (pinned to d44925c47c)

Solutions

  1. Copy a fresh access token from User Profile > Access Tokens and pass it via the access_token query parameter.
  2. Check the token was not rotated/expired/revoked and regenerate if necessary.
  3. Verify the token string is not truncated or wrapped in quotes/whitespace in your CI secret store.

Example fix

// before
curl 'http://onedev/~api/trigger-job?project=myorg/myrepo&job=CI'  // no token
// after
curl 'http://onedev/~api/trigger-job?project=myorg/myrepo&job=CI&access_token=YOUR_ONEDEV_TOKEN'
Defensive patterns

Strategy: validation

Validate before calling

if (!accessToken || accessToken.length < 20)
  throw new Error('access_token query parameter is missing or malformed');

Type guard

function hasToken(params) {
  return typeof params.access_token === 'string' && params.access_token.trim().length > 0;
}

Prevention

When it happens

Trigger: Calling GET/POST /~api/trigger-job without 'access_token' parameter, or with a token that is misspelled, truncated, expired, revoked, or generated by a different OneDev instance.

Common situations: Token copied with surrounding whitespace or quotes; old token rotated in the UI but cached in CI variables; using a JWT/OAuth token instead of an OneDev access token; storing token in config that lost the value.

Related errors


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