{"record":{"id":"424cd222a7807889","repo":"FuelLabs/fuels-ts","slug":"invalid-input-parameters-424cd2","errorCode":"INVALID_INPUT_PARAMETERS","errorMessage":"Invalid UTF-8 in the input string.","messagePattern":"Invalid UTF-8 in the input string\\.","errorType":"exception","errorClass":"FuelError","httpStatus":null,"severity":"error","filePath":"packages/utils/src/utils/toUtf8Bytes.ts","lineNumber":33,"sourceCode":"    str = stri.normalize('NFC');\n  }\n\n  const result: Array<number> = [];\n\n  for (let i = 0; i < str.length; i += 1) {\n    const c = str.charCodeAt(i);\n\n    if (c < 0x80) {\n      result.push(c);\n    } else if (c < 0x800) {\n      result.push((c >> 6) | 0xc0);\n      result.push((c & 0x3f) | 0x80);\n    } else if ((c & 0xfc00) === 0xd800) {\n      i += 1;\n      const c2 = str.charCodeAt(i);\n\n      if (i >= str.length || (c2 & 0xfc00) !== 0xdc00) {\n        throw new FuelError(\n          ErrorCode.INVALID_INPUT_PARAMETERS,\n          'Invalid UTF-8 in the input string.'\n        );\n      }\n\n      // Surrogate Pair\n      const pair = 0x10000 + ((c & 0x03ff) << 10) + (c2 & 0x03ff);\n      result.push((pair >> 18) | 0xf0);\n      result.push(((pair >> 12) & 0x3f) | 0x80);\n      result.push(((pair >> 6) & 0x3f) | 0x80);\n      result.push((pair & 0x3f) | 0x80);\n    } else {\n      result.push((c >> 12) | 0xe0);\n      result.push(((c >> 6) & 0x3f) | 0x80);\n      result.push((c & 0x3f) | 0x80);\n    }\n  }\n","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/FuelLabs/fuels-ts/blob/b3f37c91aca4aa9d5e4c0d3967f66237190826ea/packages/utils/src/utils/toUtf8Bytes.ts#L15-L51","documentation":"Thrown by toUtf8Bytes when, while encoding, a high-surrogate code unit (0xD800–0xDBFF) is either the last character in the string or is not followed by a low-surrogate (0xDC00–0xDFFF). UTF-16 requires surrogate pairs; an unpaired surrogate is invalid and cannot be encoded to UTF-8. The check fires after incrementing past the high surrogate.","triggerScenarios":"Calling toUtf8Bytes(str, form) where form is false (NFC normalization disabled) and str contains a lone high surrogate — e.g. a string built with '\\uD800' not followed by a low surrogate, or data sliced at a surrogate boundary. With form=true (default) str.normalize('NFC') usually prevents this.","commonSituations":"Disabling NFC normalization and feeding in text with broken surrogates (emoji split mid-pair, binary-as-text). Slicing a string in the middle of a surrogate pair. Constructing strings from char codes that produce unpaired surrogates. Reading non-UTF-8 bytes as a JS string.","solutions":["Keep the default form=true so the input is NFC-normalized, which repairs lone surrogates before encoding.","Sanitize input by calling str.normalize('NFC') before passing it.","Avoid slicing/substring across surrogate pair boundaries; use code-point-aware utilities.","Validate the string contains no lone surrogates with a regex check before encoding."],"exampleFix":"// before\ntoUtf8Bytes('\\uD800X', false); // throws: lone high surrogate\n\n// after\ntoUtf8Bytes('\\uD800X'.normalize('NFC')); // form defaults to true\n// or sanitize:\nconst safe = str.replace(/[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])/g, '').replace(/(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/g, '');\ntoUtf8Bytes(safe, false);","handlingStrategy":"validation","validationCode":"function hasLoneSurrogate(s: string): boolean {\n  return /[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])/.test(s) ||\n         /(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/.test(s);\n}\nconst safe = hasLoneSurrogate(str) ? str.normalize('NFC') : str;\ntoUtf8Bytes(safe);","typeGuard":"const isPairedSurrogates = (s: string): boolean =>\n  !/[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])/.test(s) &&\n  !/(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/.test(s);","tryCatchPattern":"try {\n  return toUtf8Bytes(str, form);\n} catch (e) {\n  if (e instanceof FuelError && e.code === ErrorCode.INVALID_INPUT_PARAMETERS) {\n    return toUtf8Bytes(str.normalize('NFC')); // retry with normalization\n  }\n  throw e;\n}","preventionTips":["Leave NFC normalization (form) enabled, or call .normalize('NFC') yourself.","Never slice a string across a surrogate pair boundary.","Sanitize text read from non-UTF-8 sources before encoding."],"tags":["utf8","encoding","surrogate","unicode"],"backgroundTag":null,"analyzedSha":"b3f37c91aca4aa9d5e4c0d3967f66237190826ea","analyzedAt":"2026-08-12T20:30:56.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}