fix(supervisor): drop debug-log requests cheaply when disabled (#4009)

Follow-up to #3992, which gated the send runner-side - but only for new
runner images. Existing runners still POST a debug log per line.

When `SEND_RUN_DEBUG_LOGS` is off (default), the route now drops the
request immediately: `skipBodyParsing` skips the body read/parse, a bare
handler returns 204, no wide event. The route stays registered so it
avoids the `No route match` error log; the only per-request log left is
the framework's `logger.debug` trace, suppressed at the default `info`
level. Still counted by request metrics, and 204 is non-retryable so no
retry storm.

Adds a `skipBodyParsing` flag to the internal HTTP server.
This commit is contained in:
nicktrn
2026-06-22 08:50:53 +01:00
committed by GitHub
parent f446dfaac1
commit 7621601ecd
3 changed files with 19 additions and 14 deletions
@@ -0,0 +1,5 @@
---
"@trigger.dev/core": patch
---
Add an optional `skipBodyParsing` flag to the internal HTTP server route definition, letting a route respond without reading or parsing the request body.
+9 -12
View File
@@ -596,19 +596,16 @@ export class WorkloadServer extends EventEmitter<WorkloadServerEvents> {
),
});
} else {
// Lightweight mock route without schemas
// Disabled: drop immediately without reading/parsing the body and without
// any log we can't switch off. Older runners still POST per log line; the
// route stays registered (an unregistered route would log "No route match"
// per request) but sheds the request at minimal cost. Request metrics still
// count it. 204 is non-retryable on the runner client, so no retry storm.
httpServer.route("/api/v1/workload-actions/runs/:runFriendlyId/logs/debug", "POST", {
handler: async (ctx) =>
this.wideRoute(
ctx,
"logs.debug",
"/api/v1/workload-actions/runs/:runFriendlyId/logs/debug",
"POST",
async () => {
ctx.reply.empty(204);
},
{ highFrequency: true }
),
skipBodyParsing: true,
handler: async (ctx) => {
ctx.reply.empty(204);
},
});
}
@@ -29,6 +29,9 @@ interface RouteDefinition<
querySchema?: TQuery;
bodySchema?: TBody;
keepConnectionAlive?: boolean;
/** Skip reading + parsing the request body. The handler receives `body: undefined`.
* Node drains any unconsumed body before the next keep-alive request. */
skipBodyParsing?: boolean;
handler: RouteHandler<TParams, TQuery, TBody>;
}
@@ -157,7 +160,7 @@ export class HttpServer {
return reply.empty(405);
}
const { handler, paramsSchema, querySchema, bodySchema, keepConnectionAlive } =
const { handler, paramsSchema, querySchema, bodySchema, keepConnectionAlive, skipBodyParsing } =
routeDefinition;
const params = this.parseRouteParams(route, url);
@@ -176,7 +179,7 @@ export class HttpServer {
return reply.text("Invalid query params", 400);
}
const body = await getJsonBody(req);
const body = skipBodyParsing ? undefined : await getJsonBody(req);
const parsedBody = this.optionalSchema(bodySchema, body);
if (!parsedBody.success) {