{"record":{"id":"0eac38e724695f77","repo":"gchq/CyberChef","slug":"not-a-valid-rtf-file","errorCode":null,"errorMessage":"Not a valid RTF file","messagePattern":"Not a valid RTF file","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/core/lib/FileSignatures.mjs","lineNumber":3366,"sourceCode":"\n    return stream.carve();\n}\n\n\n/**\n * RTF extractor.\n *\n * @param {Uint8Array} bytes\n * @param {number} offset\n * @returns {Uint8Array}\n */\nexport function extractRTF(bytes, offset) {\n    const stream = new Stream(bytes.slice(offset));\n\n    let openTags = 0;\n\n    if (stream.readInt(1) !== 0x7b) { // {\n        throw new Error(\"Not a valid RTF file\");\n    } else {\n        openTags++;\n    }\n\n    while (openTags > 0 && stream.hasMore()) {\n        switch (stream.readInt(1)) {\n            case 0x7b: // {\n                openTags++;\n                break;\n            case 0x7d: // }\n                openTags--;\n                break;\n            case 0x5c: // \\\n                // Consume any more escapes and then skip over the next character\n                stream.consumeIf(0x5c);\n                stream.position++;\n                break;\n            default:","sourceCodeStart":3348,"sourceCodeEnd":3384,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/lib/FileSignatures.mjs#L3348-L3384","documentation":"Thrown by extractRTF when the first byte of the (offset-adjusted) stream is not 0x7B ('{'). RTF documents must begin with an opening brace (the real signature is '{\\rtf'). A plain Error, not an OperationError, so it propagates as an internal failure.","triggerScenarios":"Calling extractRTF on non-RTF data, on RTF preceded by a BOM or leading whitespace/bytes, or with an offset that skips the opening brace.","commonSituations":"Wrong file type routed to the RTF extractor; UTF-8/UTF-16 BOM before the '{'; plain text or HTML mistaken for RTF; offset misalignment.","solutions":["Confirm the data begins with '{' (ideally the full '{\\rtf1' prolog).","Strip any leading BOM or whitespace before extraction, or pass the correct offset.","Route non-RTF input to the appropriate extractor."],"exampleFix":"// before\nextractRTF(bytesWithBom, 0);\n\n// after\nlet off = 0;\nif (bytes[0] === 0xef && bytes[1] === 0xbb && bytes[2] === 0xbf) off = 3;\nextractRTF(bytes, off);","handlingStrategy":"validation","validationCode":"function looksLikeRTF(bytes, offset = 0) {\n  return bytes.length - offset >= 1 && bytes[offset] === 0x7b; // '{'\n}\nif (!looksLikeRTF(bytes, offset)) throw new Error(\"Input is not RTF (does not start with '{')\");\nextractRTF(bytes, offset);","typeGuard":"const startsRTF = (bytes, offset = 0) => bytes[offset] === 0x7b;","tryCatchPattern":"try {\n  extractRTF(bytes, offset);\n} catch (err) {\n  if (/Not a valid RTF file/.test(err.message)) {\n    // route non-RTF input to the correct extractor\n  } else throw err;\n}","preventionTips":["Confirm the data begins with '{' (ideally the full '{\\rtf1' prolog) before calling extractRTF.","Strip a leading BOM or whitespace, or pass an offset that skips it.","Route non-RTF input to the appropriate extractor."],"tags":["rtf","file-format","validation","file-signatures"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}