-
Notifications
You must be signed in to change notification settings - Fork 42
Settle in Parallel #695
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Settle in Parallel #695
Conversation
[Feature] settle in parallel
|
🚅 Deployed to the echo-pr-695 environment in echo
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
| } | ||
|
|
||
| // Case 2: Settle failed but model succeeded | ||
| if (!settleResult && modelResult.success) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Case 2 (settle failed but model succeeded) calls handleResolveResponse after settle has already sent a 402 response, which will cause an Express error when trying to send a second response to the same request.
View Details
📝 Patch Details
diff --git a/packages/app/server/src/handlers.ts b/packages/app/server/src/handlers.ts
index 131d35d9..fb53c578 100644
--- a/packages/app/server/src/handlers.ts
+++ b/packages/app/server/src/handlers.ts
@@ -54,11 +54,7 @@ export async function handleX402Request({
provider: provider.getType(),
url: req.url,
});
- modelRequestService.handleResolveResponse(
- res,
- isStream,
- data
- );
+ // Note: settle already sent a 402 response, so we should not attempt to send another response
return;
}
Analysis
Double response error in handleX402Request Case 2
What fails: In handleX402Request() (packages/app/server/src/handlers.ts, lines 46-62), when settle fails but the model request succeeds (Case 2), the code calls modelRequestService.handleResolveResponse() after settle has already sent a 402 response via buildX402Response(), causing Express to throw "Error: Can't set headers after they are sent to the client".
How to reproduce:
- Send an X402 request where payment settlement fails (e.g., invalid payment authorization)
- Simultaneously, the model request succeeds
- The settle handler calls
buildX402Response(req, res, maxCost)which sendsres.status(402).json(resBody) - Case 2 then attempts to call
modelRequestService.handleResolveResponse(res, isStream, data)which calls eitherres.json(data)(non-streaming) orres.end()(streaming) - Express throws error because headers were already sent
Result: Error thrown and logged by error handler: "Error: Can't set headers after they are sent to the client". While the 402 response reaches the client (and the error handler checks res.headersSent before attempting another response), this is incorrect behavior - no error should be thrown since the 402 response is the correct outcome.
Expected: When settle fails and sends a 402 response indicating payment is required, no subsequent response should be attempted. The 402 response should be the final response to the client.
Root cause: Express.js specification requires exactly one response per HTTP request. Once response headers are sent, attempting to set additional headers or send another response violates this protocol and throws an error.
No description provided.