Seven months of self-hosting our own AI stack: four bugs I can point at in the changelog
We run our team's AI stack on our own hardware. The weekly development log starts the week of January 19, 2026, the repository was created on February 3, and today it sits at roughly 2,100 commits under MIT. I want to write about four things that broke, because every one of them is in the public changelog and you can check my work. No war stories I can't back up. The setup A Mac mini runs the application: API and web under PM2, with PostgreSQL, Redis, and the sandboxed agent, MCP, and artifact processes in Docker. An NVIDIA DGX Spark GB10 next to it runs vLLM, plus BGE-m3 for embeddings and FLUX for image generation. The two are connected over a private Tailscale link. That is our setup, not a requirement. Any OpenAI-compatible endpoint works. The default local model is qwen3.8-27b served through vLLM behind a LiteLLM proxy, with a 262K context window. External providers (OpenRouter, NVIDIA NIM, Ollama) only enter the picture if you register your own key, encrypted at rest with AES-256-GCM. Register nothing and every model call stays local. Bug 1: the application limit was not the real limit We accept large files as inputs to agent tasks. The application will happily allow a file well past 100 MB. That turns out not to matter. Cloudflare documents a 100 MB maximum upload size for Free and Pro zones, so a single multipart request was rejected at the edge with HTTP 413 before it ever reached the API. No validation of ours ran. No useful progress was shown. The fast workaround would have been an unproxied upload host. We kept the protected public route and changed the request shape instead: a four-step chunked protocol with a one-time claim, authentication on every operation, chunk writes that are safe to retry, and reuse of the existing storedPath contract after assembly so extraction and cleanup don't fork. The lesson is not subtle, but it cost us anyway: your app's configured limit is a claim about your app, not about the path a request actually takes. Bug 2: a sing