{"record":{"id":"545b1c0b1779f84e","repo":"quasarframework/quasar","slug":"failed-to-render-template-sourcepath-this-ma","errorCode":null,"errorMessage":"Failed to render template \"${sourcePath}\". This may break the App Extension...","messagePattern":"Failed to render template \"(.+?)\"\\. This may break the App Extension\\.\\.\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"app-vite/lib/app-extension/AppExtensionInstance.js","lineNumber":68,"sourceCode":"  if (overwritePrompt && fse.existsSync(targetPath)) {\n    const action = await promptOverwrite({\n      targetPath,\n      options: ['overwrite', 'skip'],\n      ctx\n    })\n\n    if (action === 'skip') return\n  }\n\n  if (rawCopy || isBinaryFile(sourcePath)) {\n    fse.ensureFileSync(targetPath)\n    fse.copyFileSync(sourcePath, targetPath)\n  } else {\n    const rawContent = fse.readFileSync(sourcePath, 'utf8')\n    const content = renderTemplate(rawContent, scope, renderTemplateCompileOpts)\n\n    if (content === templateRenderError) {\n      logger.warn(\n        `Failed to render template \"${sourcePath}\". This may break the App Extension...`\n      )\n    } else {\n      fse.ensureFileSync(targetPath)\n      fse.writeFileSync(targetPath, content, 'utf8')\n    }\n  }\n}\n\nasync function renderFolders({ source, rawCopy, scope }, ctx, logger) {\n  let overwrite\n  const { globSync } = await import('tinyglobby')\n  const files = globSync(['**/*'], { cwd: source })\n\n  for (const rawPath of files) {\n    const targetRelativePath = rawPath\n      .split('/')\n      .map(name => {","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/quasarframework/quasar/blob/4841521b5f635a971eb9e2710e5542efd194691b/app-vite/lib/app-extension/AppExtensionInstance.js#L50-L86","documentation":"During App Extension installation, renderFile copies template files and renders placeholders like <%= ... %> via Lodash-style templates. If template compilation/rendering throws, the content equals the sentinel templateRenderError and only this warning is emitted; the file is skipped (not written to the target). The extension's prompts/inject may then be incomplete and break at runtime.","triggerScenarios":"A template file in the extension's /template folder contains syntax that fails renderTemplate compilation (e.g. unbalanced <%= %>, ES template literal syntax unsupported by the compile options) during ext install or runInstallScript's renderFolders.","commonSituations":"Third-party App Extension shipped with a broken template; template containing code with `${...}` or special characters clashing with the template engine; extension written for an older Quasar template renderer.","solutions":["Open the logged sourcePath and fix the template syntax around the failing expression","Report/patch the App Extension (update it to a version with the template fixed)","As a workaround, copy the file manually into the target path with placeholders pre-resolved","Re-run the extension install after fixing to regenerate the skipped file"],"exampleFix":"// before (template file, unbalanced tag)\nconst x = <%= data.x %\n// after\nconst x = <%= data.x %>","handlingStrategy":"validation","validationCode":"// sanity-check extension templates before shipping/publishing\nconst fs = require('fs')\nfor (const f of templateFiles) {\n  const src = fs.readFileSync(f, 'utf8')\n  const opens = (src.match(/<%=/g) || []).length\n  const closes = (src.match(/%>/g) || []).length\n  if (opens !== closes) throw new Error(`Unbalanced EJS tags in ${f}`)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Escape literal ${ and template-like syntax in template files","Test `quasar ext add` of your extension in a scratch app before publishing","Include template files in the npm package and keep them free of renderer-unsupported syntax","After install, diff generated files against templates to catch silently skipped renders"],"tags":["app-extension","template-rendering","install"],"backgroundTag":"template-render-failed","analyzedSha":"4841521b5f635a971eb9e2710e5542efd194691b","analyzedAt":"2026-08-30T01:13:14.944Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}