{"record":{"id":"b4fa5e4b85a82028","repo":"laurent22/joplin","slug":"cannot-decode-resource-with-encoding-dataencodi","errorCode":null,"errorMessage":"Cannot decode resource with encoding: ${dataEncoding}","messagePattern":"Cannot decode resource with encoding: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/lib/import-enex.ts","lineNumber":159,"sourceCode":"\t\tresource.size = 0;\n\t\tresource.dataFilePath = `${Setting.value('tempDir')}/${resource.id}.empty`;\n\t\tawait shim.fsDriver().writeFile(resource.dataFilePath, '');\n\t};\n\n\tif (!resource.hasData) {\n\t\t// Some resources have no data, go figure, so we need a special case for this.\n\t\tawait handleNoDataResource(resource, true);\n\t} else {\n\t\t// If encoding is not specified, it defaults to base64.\n\t\t// Source: enex.dtd: <!ATTLIST data encoding (base64) \"base64\">\n\t\tconst dataEncoding = resource.dataEncoding ? resource.dataEncoding : 'base64';\n\n\t\tif (dataEncoding === 'base64') {\n\t\t\tconst decodedFilePath = `${resource.dataFilePath}.decoded`;\n\t\t\tawait decodeBase64File(resource.dataFilePath, decodedFilePath);\n\t\t\tresource.dataFilePath = decodedFilePath;\n\t\t} else if (dataEncoding) {\n\t\t\tthrow new Error(`Cannot decode resource with encoding: ${dataEncoding}`);\n\t\t}\n\n\t\tconst stats = await shim.fsDriver().stat(resource.dataFilePath);\n\t\tresource.size = stats.size;\n\n\t\tif (!resource.id) {\n\t\t\t// If no resource ID is present, the resource ID is actually the MD5\n\t\t\t// of the data. This ID will match the \"hash\" attribute of the\n\t\t\t// corresponding <en-media> tag. resourceId = md5(decodedData);\n\t\t\tresource.id = await shim.fsDriver().md5File(resource.dataFilePath);\n\t\t}\n\n\t\tif (!resource.id || !resource.size) {\n\t\t\t// Don't throw an error because it happens semi-frequently,\n\t\t\t// especially on notes that comes from the Evernote Web Clipper and\n\t\t\t// we can't do anything about it. Previously we would throw the\n\t\t\t// error \"This resource was not added because it has no ID or no\n\t\t\t// content\".","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/lib/import-enex.ts#L141-L177","documentation":"Thrown by the ENEX resource decoder when a <data> element's encoding attribute is present but not 'base64'. The importer only implements base64 decoding; the ENEX DTD defaults encoding to base64, so any other value (e.g. 'text', custom encodings) is unsupported and rejected rather than mis-decoded.","triggerScenarios":"Importing an .enex whose resource <data encoding=\"...\"> uses a non-base64 value — produced by a non-Evernote exporter, a modified ENEX, or a tool that emits a non-standard encoding attribute.","commonSituations":"Third-party note app exporting to ENEX with a different encoding; manually edited ENEX; corrupted export; an experimental/legacy Evernote format that used a non-base64 encoding.","solutions":["Re-export from the official Evernote client, which always uses base64.","Pre-process the ENEX: convert the resource data to base64 and set encoding=\"base64\" (or drop the attribute, since base64 is the default).","If you control the importer, add a decoder branch for the encountered encoding.","Strip the offending resource from the ENEX if it's non-essential."],"exampleFix":"// before\nif (dataEncoding === 'base64') { /* decode */ }\nelse if (dataEncoding) { throw new Error(`Cannot decode resource with encoding: ${dataEncoding}`); }\n// after - fall back to treating unencoded content as raw text/binary\nif (dataEncoding === 'base64') { await decodeBase64File(...); }\nelse if (dataEncoding === 'none' || dataEncoding === 'text') { resource.dataFilePath = rawPath; }\nelse { throw new Error(`Unsupported resource encoding: ${dataEncoding}`); }","handlingStrategy":"validation","validationCode":"if (resource.dataEncoding && resource.dataEncoding !== 'base64') {\n  throw new Error(`Unsupported ENEX data encoding '${resource.dataEncoding}'; convert to base64 before import.`);\n}","typeGuard":"function isSupportedEncoding(enc: string | undefined): boolean {\n  return !enc || enc === 'base64';\n}","tryCatchPattern":"try {\n  await importEnexResource(resource);\n} catch (e) {\n  if (/Cannot decode resource with encoding/.test(e.message)) {\n    // convert the resource data to base64 offline, then retry; or skip the resource\n    logger.warn('Skipping resource with unsupported encoding:', e.message);\n    return;\n  }\n  throw e;\n}","preventionTips":["Re-export from official Evernote to guarantee base64 encoding.","Pre-process ENEX: convert non-base64 data and set encoding=\"base64\".","Validate the encoding attribute before invoking the decoder.","Strip non-essential malformed resources from the ENEX."],"tags":["import","enex","evernote","encoding","base64"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}