diff --git a/api/router.ts b/api/router.ts index 1baec7e..a67f7d7 100644 --- a/api/router.ts +++ b/api/router.ts @@ -5,6 +5,7 @@ import { isSuperAdmin } from '@@/super-admin'; import * as errors from '@@/custom-errors'; import { mountPrefix } from '@@/plugins/manifest'; import { onAccountLifecycle } from '@@/account-lifecycle'; +import { registerProxiedPrefix } from '@@/sidecar/proxied-prefixes'; import { manifest } from '../manifest'; import { getVaultServerUrl } from './sidecar-server'; import { publicVaultRouter } from './public-router'; @@ -41,6 +42,21 @@ import { // `router`, so there is nowhere for it to inject the plugin's own directory name. const PREFIX = `/api${mountPrefix({ appName: 'vault', manifest })}`; +/* + Tell bodyParser to keep its hands off this prefix. + + Everything under it is either forwarded verbatim to the sidecar or parsed by the handler itself + (`ctx.req.json()`), so nothing here wants a body read for it. The platform's bodyParser reads JSON + and form bodies on the protected router, which DISTURBS the request stream — and the catch-all + proxy below then forwards `ctx.req.raw.body`, an already-consumed stream. Bun's fetch throws on it, + the proxy reports 'sidecar unreachable', and the client is told the server is down while every + bodyless GET keeps working. + + Core's own sidecars never hit this because `createSidecarProxy` registers the prefix for them. This + router proxies by hand, so it has to say so itself — which extraction dropped on 2026-08-18. +*/ +registerProxiedPrefix(PREFIX); + export const router = createRouter(); /*