{"record":{"id":"b8b1a3868f1ad0e8","repo":"jackwener/OpenCLI","slug":"file-could-not-be-decoded-as-utf-8-text-path","errorCode":null,"errorMessage":"File could not be decoded as UTF-8 text: ${path}","messagePattern":"File could not be decoded as UTF-8 text: (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/_atlassian/shared.js","lineNumber":312,"sourceCode":"    let fileStat;\n    try {\n        fileStat = await stat(path);\n    } catch {\n        throw new ArgumentError(`File not found: ${path}`);\n    }\n    if (!fileStat.isFile()) {\n        throw new ArgumentError(`File must be a readable text file: ${path}`);\n    }\n    let raw;\n    try {\n        raw = await readFile(path);\n    } catch {\n        throw new ArgumentError(`File could not be read: ${path}`);\n    }\n    try {\n        return new TextDecoder('utf-8', { fatal: true }).decode(raw);\n    } catch {\n        throw new ArgumentError(`File could not be decoded as UTF-8 text: ${path}`);\n    }\n}\n\nexport function htmlEscape(value) {\n    return String(value ?? '')\n        .replace(/&/g, '&amp;')\n        .replace(/</g, '&lt;')\n        .replace(/>/g, '&gt;')\n        .replace(/\"/g, '&quot;');\n}\n\nexport function htmlToMarkdown(html) {\n    return coreHtmlToMarkdown(String(html ?? ''));\n}\n\nfunction applyAdfMarks(text, marks = []) {\n    let out = text;\n    for (const mark of marks) {","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/_atlassian/shared.js#L294-L330","documentation":"The file is read as raw bytes and decoded with TextDecoder('utf-8', { fatal: true }). If the bytes are not valid UTF-8 (e.g. Latin-1, UTF-16, binary), decoding throws and the function raises ArgumentError 'File could not be decoded as UTF-8 text: <path>'.","triggerScenarios":"Passing a file whose bytes are not valid UTF-8: Windows-1252/Latin-1 exports, UTF-16 files with BOM, or binary content (PDF, images, zip) supplied via --file.","commonSituations":"Files exported from Windows tools in a legacy codepage; files saved as UTF-16 by PowerShell (Out-File default); accidentally passing a binary attachment instead of a text/markdown file.","solutions":["Convert the file to UTF-8 first, e.g. `iconv -f WINDOWS-1252 -t UTF-8 in.txt > out.txt` (detect with `file -i <path>`).","Re-save the file as UTF-8 in your editor (VS Code: 'Save with Encoding > UTF-8').","Ensure you are passing a text file, not a binary document, to --file."],"exampleFix":"// before\n$ file notes.txt\nnotes.txt: ISO-8859 text\n// after\n$ iconv -f ISO-8859-1 -t UTF-8 notes.txt > notes-utf8.txt\n$ cli jira comment --issue PROJ-1 --file notes-utf8.txt","handlingStrategy":"validation","validationCode":"const raw = await readFile(p);\ntry { new TextDecoder('utf-8', { fatal: true }).decode(raw); }\ncatch { throw new Error(`${p} is not valid UTF-8; convert it first`); }","typeGuard":"const isUtf8File = async (p) => {\n  try { new TextDecoder('utf-8', { fatal: true }).decode(await readFile(p)); return true; }\n  catch { return false; }\n};","tryCatchPattern":"try {\n  const text = await readUtf8File(p);\n} catch (err) {\n  if (err.name === 'ArgumentError' && err.message.includes('UTF-8')) {\n    console.error(`Convert ${p} to UTF-8, e.g. iconv -f WINDOWS-1252 -t UTF-8.`);\n  }\n  throw err;\n}","preventionTips":["Save editor files as UTF-8 (not UTF-16/Latin-1).","Detect encoding with `file -i <path>` before passing non-ASCII content.","Never pass binary documents (PDF/images) to text-oriented --file options."],"tags":["encoding","utf-8","argument-validation","cli"],"backgroundTag":"invalid-utf8-encoding","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}