{"record":{"id":"8b1fc402f3e00d33","repo":"nexu-io/open-design","slug":"file-relpath-contentbytes-bytes-exceeds-re","errorCode":null,"errorMessage":"file ${relPath} (${contentBytes} bytes) exceeds remaining budget","messagePattern":"file (.+?) \\((.+?) bytes\\) exceeds remaining budget","errorType":"exception","errorClass":"BudgetExceededError","httpStatus":null,"severity":"warning","filePath":"apps/daemon/src/mcp.ts","lineNumber":3275,"sourceCode":"  if (!resp.ok) {\n    const body = await safeText(resp);\n    throw new Error(`daemon ${resp.status} on ${url}: ${body || resp.statusText}`);\n  }\n  const mime = ((resp.headers.get('content-type') || 'application/octet-stream').split(';')[0] ?? 'application/octet-stream').trim();\n  const headerSize = Number(resp.headers.get('content-length'));\n  const size = Number.isFinite(headerSize) && headerSize >= 0 ? headerSize : null;\n  if (!isTextualMime(mime)) {\n    return { name: relPath, mime, size, content: null, binary: true };\n  }\n  // If the server advertises a size that already exceeds our remaining\n  // budget, skip reading the body to avoid a large allocation.\n  if (size !== null && size > remainingBytes) {\n    throw new BudgetExceededError(`file ${relPath} (${size} bytes) exceeds remaining budget`);\n  }\n  const content = await resp.text();\n  const contentBytes = Buffer.byteLength(content, 'utf8');\n  if (contentBytes > remainingBytes) {\n    throw new BudgetExceededError(\n      `file ${relPath} (${contentBytes} bytes) exceeds remaining budget`,\n    );\n  }\n  return { name: relPath, mime, size: size ?? contentBytes, content, binary: false };\n}\n\n// Patterns common to HTML and CSS (also fine to run on plain markdown).\nconst HTML_REF_PATTERNS = [\n  /<script\\b[^>]*\\bsrc=[\"']([^\"']+)[\"']/gi,\n  /<link\\b[^>]*\\bhref=[\"']([^\"']+)[\"']/gi,\n  /<img\\b[^>]*\\bsrc=[\"']([^\"']+)[\"']/gi,\n  /<source\\b[^>]*\\bsrc=[\"']([^\"']+)[\"']/gi,\n  /<video\\b[^>]*\\bsrc=[\"']([^\"']+)[\"']/gi,\n  /<audio\\b[^>]*\\bsrc=[\"']([^\"']+)[\"']/gi,\n  /<iframe\\b[^>]*\\bsrc=[\"']([^\"']+)[\"']/gi,\n];\n\nconst CSS_REF_PATTERNS = [","sourceCodeStart":3257,"sourceCodeEnd":3293,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/mcp.ts#L3257-L3293","documentation":"Thrown as a BudgetExceededError after reading the body: the actual UTF-8 byte length of the content exceeds the remaining budget, even though the Content-Length header did not (or was absent/zero). This is the second-line guard that catches misreported or chunked/gzip-decoded sizes.","triggerScenarios":"Server omitted or under-reported Content-Length (e.g. chunked transfer-encoding); the body decoded to more bytes than advertised; a text file slightly larger than the residual budget after the header check passed.","commonSituations":"Compressed/streamed responses where header size disagrees with decoded size; UTF-8 multibyte content inflating beyond a byte-counted budget; budgets set just under the file size.","solutions":["Raise the remainingBytes budget for the fetch operation.","Read the file in pages via offset/limit so each chunk fits the budget.","Pre-filter large files out of the bundle using the directory listing's size metadata.","If the header/body disagreement is a daemon bug, file an issue with the path and sizes."],"exampleFix":"// before: whole-file read overflows residual budget\nconst file = await getFile(baseUrl, project, bigTextPath, active, resolved, 0, 2000, remainingBytes);\n// after: paged read\nconst page = await getFile(baseUrl, project, bigTextPath, active, resolved, 0, 500, remainingBytes);","handlingStrategy":"try-catch","validationCode":"const contentBytes = Buffer.byteLength(content, 'utf8');\nif (contentBytes > remainingBytes) throw new BudgetExceededError('content exceeds budget');","typeGuard":null,"tryCatchPattern":"try {\n  return await fetchRawFile(baseUrl, projectId, relPath, remainingBytes, headers);\n} catch (e) {\n  if (e instanceof BudgetExceededError) return await pagedRead(baseUrl, projectId, relPath, remainingBytes);\n  throw e;\n}","preventionTips":["Page large reads via offset/limit.","Treat BudgetExceededError as a signal to shrink scope, not a fatal error.","Report header/body size disagreements to daemon maintainers."],"tags":["mcp","files","budget","performance"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}