{"record":{"id":"bf45449b87365d73","repo":"janhq/jan","slug":"too-large","errorCode":null,"errorMessage":"TOO_LARGE","messagePattern":"TOO_LARGE","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"web-app/src/containers/CoworkPreviewPanel.tsx","lineNumber":109,"sourceCode":"    if (kind === 'file') {\n      setState({ status: 'unsupported', path })\n      return\n    }\n    setState({ status: 'loading', path })\n\n    void (async () => {\n      const url = getServiceHub().core().convertFileSrc(abs)\n      if (isAssetKind(kind)) {\n        // The element streams the file itself, so there is nothing to fetch and\n        // a large video costs nothing to \"open\".\n        if (alive) setState({ status: 'ready', path, kind, assetUrl: url })\n        return\n      }\n      try {\n        const res = await fetch(url)\n        if (!res.ok) throw new Error(String(res.status))\n        const size = Number(res.headers.get('content-length') ?? 0)\n        if (size > MAX_PREVIEW_BYTES) throw new Error(TOO_LARGE)\n        const content = await res.text()\n        if (content.length > MAX_PREVIEW_BYTES) throw new Error(TOO_LARGE)\n        if (!alive) return\n        setState({\n          status: 'ready',\n          path,\n          kind,\n          content,\n          unresolvedRefs: kind === 'html' ? unresolvedRefs(content) : undefined,\n          externalRefs: kind === 'html' ? externalRefs(content) : undefined,\n        })\n      } catch (e) {\n        if (!alive) return\n        setState({\n          status: 'failed',\n          path,\n          reason: e instanceof Error ? e.message : String(e),\n        })","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/janhq/jan/blob/7205d770c1e097c3daf35a911176410e93bc5564/web-app/src/containers/CoworkPreviewPanel.tsx#L91-L127","documentation":"The preview loader enforces MAX_PREVIEW_BYTES twice: once via the content-length header before reading, once on the decoded text length. Exceeding either throws new Error(TOO_LARGE), which the panel renders as a 'file too large to preview' state instead of loading the content.","triggerScenarios":"Opening a text preview for a file whose content-length header exceeds MAX_PREVIEW_BYTES, or whose decoded body is longer than the limit (e.g. large log, dataset, or binary file misdetected as text).","commonSituations":"Clicking a preview on multi-hundred-MB data files; content-length missing so the limit is only caught after downloading the whole body; binary assets routed into the text preview path.","solutions":["Choose a different preview mode (e.g. open externally) for large files.","Increase MAX_PREVIEW_BYTES if legitimately larger text previews are needed.","Range-request only the first N bytes for a truncated preview.","Fix kind detection so binaries don't enter the text preview path."],"exampleFix":"// before\nif (size > MAX_PREVIEW_BYTES) throw new Error(TOO_LARGE)\n// after\nif (size > MAX_PREVIEW_BYTES) {\n  throw new Error(`${TOO_LARGE} (${size} > ${MAX_PREVIEW_BYTES} bytes)`)\n}","handlingStrategy":"validation","validationCode":"const head = await fetch(url, { method: 'HEAD' })\nconst size = Number(head.headers.get('content-length') ?? 0)\nif (head.ok && size > MAX_PREVIEW_BYTES) {\n  return { status: 'too-large' }\n}","typeGuard":"const isPreviewableSize = (size: number): boolean =>\n  Number.isFinite(size) && size > 0 && size <= MAX_PREVIEW_BYTES","tryCatchPattern":"try {\n  const content = await loadPreview(url)\n  setState({ status: 'ready', content })\n} catch (err) {\n  if (err.message === TOO_LARGE) {\n    setState({ status: 'too-large' })\n  } else {\n    setState({ status: 'error', message: err.message })\n  }\n}","preventionTips":["HEAD-check content-length before downloading preview bodies.","Define a sane MAX_PREVIEW_BYTES for typical text files (logs, code, configs).","Route binary/large files to download or external open instead of text preview.","Treat missing content-length as unknown and cap the streamed read."],"tags":["preview","size-limit"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"7205d770c1e097c3daf35a911176410e93bc5564","analyzedAt":"2026-09-17T14:27:30.100Z","contentChangedAt":"2026-09-17T14:27:30.100Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}