theonedev/onedev · error · UnsupportedOperationException

This feature requires an active subscription

Error message

This feature requires an active subscription

What it means

Issue work logs (time tracking records) are a premium feature. The GET /api/issues/{issueId}/works/{workId} endpoint (getWork) throws UnsupportedOperationException when no active subscription exists, before even loading the work record.

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/IssueWorkResource.java:48

@Singleton
public class IssueWorkResource {

	private final IssueWorkService workService;
	
	private final SubscriptionService subscriptionService;
	
	@Inject
	public IssueWorkResource(IssueWorkService workService, SubscriptionService subscriptionService) {
		this.workService = workService;
		this.subscriptionService = subscriptionService;
	}

	@Api(order=100)
	@Path("/{workId}")
	@GET
	public IssueWork getWork(@PathParam("workId") Long workId) {
		if (!subscriptionService.isSubscriptionActive())
			throw new UnsupportedOperationException("This feature requires an active subscription");
		IssueWork work = workService.load(workId);
    	if (!SecurityUtils.canAccessIssue(work.getIssue()))  
			throw new UnauthorizedException();
    	return work;
	}
	
	@Api(order=200, description="Log new issue work")
	@POST
	public Long createWork(@NotNull IssueWork work) {
		if (!subscriptionService.isSubscriptionActive()) 
			throw new NotAcceptableException("This feature requires an active subscription");
		if (!work.getIssue().getProject().isTimeTracking())
			throw new NotAcceptableException("Time tracking not enabled for project");
		
    	if (!SecurityUtils.canAccessIssue(work.getIssue()) 
				|| !SecurityUtils.isAdministrator() && !work.getUser().equals(SecurityUtils.getAuthUser())) {
			throw new UnauthorizedException();
		}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Activate or renew the subscription in server license settings.
  2. Skip work-log endpoints when running unlicensed; read time data elsewhere.
  3. Gate the integration on subscription state before calling the endpoint.

Example fix

// before
GET /api/issues/12/works/3  -> UnsupportedOperationException
// after: activate subscription (Server Setting -> Subscription), then retry GET
Defensive patterns

Strategy: try-catch

Validate before calling

const sub = await getSubscriptionStatus();
if (!sub.active) throw new Error('Issue work endpoints require an active subscription');

Type guard

function subscriptionActive(serverInfo) {
  return serverInfo?.subscriptionStatus === 'ACTIVE';
}

Try / catch

try {
  return await api.getIssueWork(issueId, workId);
} catch (e) {
  if (e instanceof UnsupportedOperationError || /requires an active subscription/.test(String(e.message)))
    return null; // premium feature unavailable
  throw e;
}

Prevention

When it happens

Trigger: GET request to the issue work resource path ({issueId}/works/{workId}) on a OneDev instance without an active subscription.

Common situations: Scripting against a free/community installation; subscription lapsed; querying work logs for audit/reporting in an unlicensed environment.

Related errors


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