{"record":{"id":"677b9c895c8b6553","repo":"laurent22/joplin","slug":"plugin-assets-must-have-property-mime-set-to-te","errorCode":null,"errorMessage":"Plugin assets must have property \"mime\" set to \"text/css\" or have a filename ending with \".css\"","messagePattern":"Plugin assets must have property \"mime\" set to \"text/css\" or have a filename ending with \"\\.css\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/editor/CodeMirror/pluginApi/PluginLoader.ts","lineNumber":179,"sourceCode":"\t\t\t\t\tlet assetText: string = asset.text;\n\t\t\t\t\tlet assetMime: string = asset.mime;\n\n\t\t\t\t\tif (!asset.inline) {\n\t\t\t\t\t\tif (!asset.name) {\n\t\t\t\t\t\t\tthrow new Error('Non-inline asset missing required property \"name\"');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (assetMime !== 'text/css' && !asset.name.endsWith('.css')) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`Non-css assets are not supported by the CodeMirror 6 editor. (Asset path: ${asset.name})`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tassetText = await plugin.loadCssAsset(asset.name);\n\t\t\t\t\t\tassetMime = 'text/css';\n\t\t\t\t\t}\n\n\t\t\t\t\tif (assetMime !== 'text/css') {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t'Plugin assets must have property \"mime\" set to \"text/css\" or have a filename ending with \".css\"',\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tcssStrings.push(assetText);\n\t\t\t\t}\n\n\t\t\t\taddStyles(cssStrings);\n\t\t\t}\n\t\t});\n\n\t\tthis.loadedContentScriptIds.push(contentScriptToId(plugin));\n\t}\n\n\tpublic remove() {\n\t\tthis.pluginScriptsContainer.remove();\n\t}\n}","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/editor/CodeMirror/pluginApi/PluginLoader.ts#L161-L197","documentation":"Thrown after the inline/non-inline branch when assetMime is still not 'text/css'. This catches inline assets whose mime was wrong or missing (non-inline assets that passed the earlier check have already had assetMime normalized to text/css on line 175). It is the final guarantee that only CSS reaches addStyles.","triggerScenarios":"An inline asset with mime omitted or set to something other than 'text/css' (e.g. 'text/javascript', undefined); an inline asset with text present but mime = 'application/json'. Because name is irrelevant for inline assets, the .css-extension fallback does not apply here.","commonSituations":"Plugin author set inline: true and text but forgot mime; mime was set to a wrong value copied from another asset; the asset object was constructed with mime = null.","solutions":["Set asset.mime = 'text/css' on every inline CSS asset.","Remove the asset if it is not CSS.","Construct assets via a helper that defaults mime to 'text/css'."],"exampleFix":"// before\nassets: () => [{ inline: true, text: '.cm-editor { color: red }' }],\n// after\nassets: () => [{ inline: true, mime: 'text/css', text: '.cm-editor { color: red }' }],","handlingStrategy":"validation","validationCode":"function assertInlineCssMime(a) {\n  if (a.inline && a.mime !== 'text/css') throw new Error('Inline asset must be text/css');\n}\nassets().forEach(assertInlineCssMime);","typeGuard":"function isInlineCssAsset(a) { return a.inline === true && a.mime === 'text/css'; }","tryCatchPattern":"try {\n  loader.setPlugins(contentScripts);\n} catch (e) {\n  if (/must have property \"mime\"/.test(e.message)) {\n    // default mime to text/css and retry, or skip\n  } else throw e;\n}","preventionTips":["Always set mime: 'text/css' on inline CSS assets.","Use a factory helper that defaults mime when building asset objects."],"tags":["editor","codemirror","plugin","asset","css"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}