theonedev/onedev · error · ExplicitException

Unable to update attributes as agent is offline

Error message

Unable to update attributes as agent is offline

What it means

In updateAttributes, after the administrator check, OneDev refuses to sync attributes when the target agent is offline, throwing ExplicitException with this message. Attribute changes are pushed to the live agent, so they can only be applied while it is connected.

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/AgentResource.java:89

    		@QueryParam("offset") @Api(example="0") int offset, 
    		@QueryParam("count") @Api(example="100") int count) {
    	if (!SecurityUtils.isAdministrator()) 
			throw new UnauthorizedException();

		var parsedQuery = AgentQuery.parse(query, false);
    	
    	return agentService.query(parsedQuery, offset, count);
    }
	
	@Api(order=400)
	@Path("/{agentId}/attributes")
	@POST
    public Response updateAttributes(@PathParam("agentId") Long agentId, Map<String, String> attributes) {
    	if (!SecurityUtils.isAdministrator()) 
			throw new UnauthorizedException();
    	Agent agent = agentService.load(agentId);
    	if (!agent.isOnline())
    		throw new ExplicitException("Unable to update attributes as agent is offline");
		var oldAuditContent = VersionedXmlDoc.fromBean(agent.getAttributeMap()).toXML();
		agentAttributeService.syncAttributes(agent, attributes);
		agentService.attributesUpdated(agent);
		var newAuditContent = VersionedXmlDoc.fromBean(agent.getAttributeMap()).toXML();
		auditService.audit(null, "changed attributes of agent \"" + agent.getName() + "\" via RESTful API", 
				oldAuditContent, newAuditContent);
		return Response.ok().build();
    }
	
}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Start the agent (or fix its connection) so it shows Online in Admin > Agents, then retry
  2. Confirm the agentId refers to a currently connected agent (GET /~api/agents and check status)
  3. If attributes must be changed offline, edit them when the agent reconnects or re-register the agent
  4. Automate by waiting/polling until agent.isOnline() before posting

Example fix

// before
POST /~api/agents/7/attributes ...  // agent 7 offline
// after
# start agent service first, e.g.
systemctl start onedev-agent
# then retry the POST once agent is online
Defensive patterns

Strategy: validation

Validate before calling

// check agent connectivity before POST
Agent a = adminClient.getAgent(agentId);
if (!a.getStatus().equals("ONLINE")) throw new IllegalStateException("Agent offline; attributes cannot be updated");

Type guard

boolean canUpdateAttributes(Agent a) { return a.isOnline(); }

Try / catch

try { client.updateAttributes(id, attrs); } catch (ClientErrorException e) { if (String.valueOf(e.getResponse().readEntity(String.class)).contains("offline")) scheduleRetryAfterReconnect(id); }

Prevention

When it happens

Trigger: POST /~api/agents/{agentId}/attributes with admin credentials while the agent process is stopped, disconnected, or not yet registered/online.

Common situations: Updating attributes during agent maintenance window when the agent service is down; agent container crashed; typo'd agentId pointing to a decommissioned agent; firewall/network drop leaving the agent offline.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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