{"record":{"id":"fbf4e7965ddff23b","repo":"overleaf/overleaf","slug":"resulting-string-would-be-too-long","errorCode":null,"errorMessage":"resulting string would be too long","messagePattern":"resulting string would be too long","errorType":"validation","errorClass":"TooLongError","httpStatus":null,"severity":"error","filePath":"libraries/overleaf-editor-core/lib/operation/text_operation.js","lineNumber":334,"sourceCode":"        result += op.insertion\n      } else if (op instanceof RemoveOp) {\n        file.comments.applyDelete(new Range(result.length, op.length))\n        inputCursor += op.length\n      } else {\n        throw new UnprocessableError('Unknown ScanOp type during apply')\n      }\n    }\n\n    if (inputCursor !== str.length) {\n      throw new TextOperation.ApplyError(\n        \"The operation didn't operate on the whole string.\",\n        operation,\n        str\n      )\n    }\n\n    if (result.length > TextOperation.MAX_STRING_LENGTH) {\n      throw new TextOperation.TooLongError(operation, result.length)\n    }\n\n    file.trackedChanges.applyTextOperation(this)\n\n    file.content = result\n  }\n\n  /**\n   * @inheritdoc\n   * @param {number} length of the original string; non-negative\n   * @return {number} length of the new string; non-negative\n   */\n  applyToLength(length) {\n    const operation = this\n    if (length !== operation.baseLength) {\n      throw new TextOperation.ApplyError(\n        \"The operation's base length must be equal to the string's length.\",\n        operation,","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/overleaf/overleaf/blob/28ad3b03b71cb4311decdcb55c36b33ec10d72db/libraries/overleaf-editor-core/lib/operation/text_operation.js#L316-L352","documentation":"After applying, if the resulting string exceeds TextOperation.MAX_STRING_LENGTH, the library throws TooLongError instead of materializing an oversized document in memory. This guards against runaway insertions (often from bugs or malicious clients) exhausting memory or breaking downstream persistence limits.","triggerScenarios":"file.apply(op) where result.length > TextOperation.MAX_STRING_LENGTH — e.g. huge paste inserts, repeated large appends, or a client submitting ops that grow the file beyond the configured cap.","commonSituations":"Users pasting very large documents; a client bug in a loop that keeps inserting; attackers inflating documents; deployments that lowered MAX_STRING_LENGTH below existing document sizes so valid-looking ops now fail.","solutions":["Check TextOperation.MAX_STRING_LENGTH and the current content length before building/applying big insertions","Split the change into smaller operations, or increase MAX_STRING_LENGTH if your storage backend truly supports larger files","Reject oversized inserts at the API/websocket layer with a clear 413-style error to the client","Detect runaway insertion loops client-side (cap insert size per op batch)"],"exampleFix":"// before\nfile.apply(new TextOperation().insert(hugeString)) // throws TooLongError\n// after\nif (file.getContent().length + hugeString.length > TextOperation.MAX_STRING_LENGTH) {\n  throw new Error('document too large')\n}\nfile.apply(new TextOperation().insert(hugeString))","handlingStrategy":"validation","validationCode":"function fitsLengthLimit(file, insertText) {\n  return file.getContent().length + insertText.length <= TextOperation.MAX_STRING_LENGTH\n}\n// guard: if (!fitsLengthLimit(file, text)) reject or split the insert","typeGuard":null,"tryCatchPattern":"try {\n  file.apply(op)\n} catch (err) {\n  if (err.name === 'TooLongError') {\n    logger.warn({ size: err.size }, 'resulting document too long')\n    throw new ClientError(413, 'document exceeds maximum length')\n  }\n  throw err\n}","preventionTips":["Enforce a client-side insert size cap below MAX_STRING_LENGTH","Check content length + insert length before applying large ops","Monitor MAX_STRING_LENGTH config changes when upgrading or resizing storage limits"],"tags":["ot","limits","apply"],"backgroundTag":"document-too-long","analyzedSha":"28ad3b03b71cb4311decdcb55c36b33ec10d72db","analyzedAt":"2026-09-03T02:10:22.807Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}