fix(control-plane): make max upload size configurable (#2313) (#2319)

The Next.js auth middleware buffers proxied request bodies and truncates
anything over its default 10MB limit before /api/files/retain can parse
the multipart form, so single uploads >10MB silently fail with
"Failed to parse body as FormData".

Set experimental.proxyClientMaxBodySize, defaulting to 100MB to match the
dataplane's HINDSIGHT_API_FILE_CONVERSION_MAX_BATCH_SIZE_MB default and
overridable via the new HINDSIGHT_CP_MAX_UPLOAD_SIZE env var (size string
or byte count).
This commit is contained in:
Nicolò Boschi
2026-06-23 09:55:02 +02:00
committed by GitHub
parent dcabd76911
commit 5543992d7d
2 changed files with 16 additions and 0 deletions
+15
View File
@@ -11,6 +11,18 @@ const distDir = process.env.PORT && process.env.PORT !== '9999'
? `.next-${process.env.PORT}`
: '.next';
// Maximum upload/request body size for file retain. Next.js buffers request
// bodies that pass through middleware/proxy (the auth middleware does, for
// /api/files/retain) and truncates anything over this limit (default 10MB),
// which silently corrupts large document uploads. Default to 100MB to match the
// dataplane's HINDSIGHT_API_FILE_CONVERSION_MAX_BATCH_SIZE_MB default; accepts a
// human-readable size string ('100mb', '1gb') or a number of bytes.
type SizeLimit = NonNullable<NonNullable<NextConfig['experimental']>['proxyClientMaxBodySize']>;
const maxUploadEnv = process.env.HINDSIGHT_CP_MAX_UPLOAD_SIZE;
const maxUploadBodySize: SizeLimit = maxUploadEnv
? (/^\d+$/.test(maxUploadEnv) ? Number(maxUploadEnv) : (maxUploadEnv as SizeLimit))
: '100mb';
const nextConfig: NextConfig = {
output: 'standalone',
distDir,
@@ -18,6 +30,9 @@ const nextConfig: NextConfig = {
assetPrefix: basePath,
// Disable request logging in production
logging: false,
experimental: {
proxyClientMaxBodySize: maxUploadBodySize,
},
// Set the monorepo root explicitly to avoid detecting wrong lockfiles in parent directories
turbopack: {
root: path.resolve(__dirname, '..'),
@@ -1747,6 +1747,7 @@ The Control Plane is the web UI for managing memory banks.
| `HINDSIGHT_CP_DATAPLANE_API_URL` | URL of the API service | `http://localhost:8888` |
| `HINDSIGHT_CP_DATAPLANE_API_KEY` | Bearer token the Control Plane sends as `Authorization: Bearer <key>` on every request to the API service. Required when the API service is auth-protected; omit for a public API. | *(none — no `Authorization` header sent)* |
| `HINDSIGHT_CP_ACCESS_KEY` | Access key to protect the Control Plane UI. When set, users must enter this key to log in. | *(none — auth disabled)* |
| `HINDSIGHT_CP_MAX_UPLOAD_SIZE` | Maximum size of a single file-upload request the Control Plane accepts before truncating it. Accepts a size string (`100mb`, `1gb`) or a number of bytes. Raise this to upload files larger than the default, and keep it in line with the API's `HINDSIGHT_API_FILE_CONVERSION_MAX_BATCH_SIZE_MB`. | `100mb` |
| `NEXT_PUBLIC_BASE_PATH` | Base path for Control Plane UI when behind reverse proxy (e.g., `/hindsight`) | `""` (root) |
```bash