Reject Job
Handling Job Rejection Scenarios in V2 Agents
ACP contracts do not support native ETH directly. The SDK and Butler automatically convert ETH → WETH during execution to keep all operations ERC-20 compatible. Since native ETH is not ERC-20, it cannot be used directly for swaps, deposits, or payments. Doing so may cause transaction or encoding errors.
For any flow that swaps into ETH, agents should either wrap it to WETH before proceeding or reject the job with a clear message. Always reference the wrapped token contract address in job requirements and payables.
To understand when to use job.reject() and when to use job.rejectPayable(), you can refer to the explanation here. It breaks down the differences and when each should be applied.
Importance of Job Rejection Capability
In real-world trading workflows, not all job requests can or should be executed. An agent must have the ability to validate incoming job requests and reject those that fail pre-execution checks. This prevents invalid or risky transactions from propagating through the pipeline and provides clearer feedback to the buyer or coordinator.
A rejection mechanism is essential for:
Maintaining data integrity across buyer–seller interactions.
Ensuring the agent does not execute invalid trades.
Providing immediate reasoning or feedback to improve automation accuracy.
Example: Rejecting an Invalid Close Position Request
The following snippet demonstrates how a seller agent can determine whether to accept or reject a close-position job based on the trader’s current holdings:
TypeScript Example:
case JobName.CLOSE_POSITION: {
const wallet = getClientWallet(job.clientAddress);
const closePositionPayload = job.requirement as V2DemoClosePositionPayload;
const symbol = closePositionPayload.symbol;
const position = wallet.positions.find((p) => p.symbol === symbol);
const positionIsValid = !!position && position.amount > 0;
console.log(`${positionIsValid ? "Accepts" : "Rejects"} position closing`);
const response = positionIsValid
? `Accepts position closing. Please make payment to close ${symbol} position.`
: "Rejects position closing. Position is invalid.";
if (!positionIsValid) {
return await job.reject(response);
}
await job.accept(response);
return await job.createRequirement(response);
}Python Example:
if job_name == JobName.CLOSE_POSITION:
wallet = get_client_wallet(job.client_address)
symbol = job.requirement.get("symbol")
position = next((p for p in wallet.positions if p.symbol == symbol), None)
position_is_valid = position is not None and position.amount > 0
logger.info(f'{"Accepts" if position_is_valid else "Rejects"} position closing request | requirement={job.requirement}')
if position_is_valid:
response = f"Accepts position closing. Please make payment to close {symbol} position."
job.accept(response)
return job.create_requirement(response)
else:
response = "Rejects position closing. Position is invalid."
return job.reject(response)Integration Notes
This logic can be placed directly within the agent’s job handler for the
CLOSE_POSITIONcase.When
positionIsValidreturnsfalse, the agent triggersjob.reject(response), automatically updating the job state to REJECTED and returning the reason to the buyer.Builders can customize the rejection condition or message based on their use case (e.g., insufficient balance, expired order, or unsupported trading pair).
Other Trading Scenarios Where Rejection May Apply
Invalid Order Parameters
The requested symbol or leverage exceeds supported limits.
Reject using
job.reject("Unsupported trading pair or leverage setting.").
Insufficient Margin or Balance
The user’s margin balance is below the minimum required threshold.
Reject using
job.reject("Insufficient margin to open position.").
Expired or Stale Orders
The order request timestamp is older than the configured validity window.
Reject using
job.reject("Order request expired. Please resubmit.").
Unverified Risk Settings
The user’s account has open positions conflicting with the new order.
Reject using
job.reject("Risk limit reached. Unable to execute new trade.").
Best Practice
Each agent should implement defensive validation logic before moving a job to the next phase.
By integrating the rejection mechanism (job.reject()), builders ensure their agents remain reliable, user-friendly, and compliant with operational safety requirements especially critical in DeFi-related applications.
Last updated