quasarframework/quasar · warning

renderFile() - cannot locate

Error message

renderFile() - cannot locate ${relativeSourcePath}. Skipping...

What it means

api.renderFile(relativeSourcePath, relativeTargetPath, scope) renders a single template file. This warning means the source file, resolved relative to the directory of the file calling renderFile(), does not exist, so rendering is skipped.

Solutions

  1. Correct relativeSourcePath so it is relative to the install-script file calling renderFile().
  2. Verify the file exists in the installed extension under node_modules (watch for case mismatches).
  3. If you own the extension, include the file in package.json 'files' and republish.
  4. If a folder was meant, use api.render() instead.

Example fix

// before: path relative to extension root
api.renderFile('templates/env.txt', '.env.example')
// after: relative to this install script
api.renderFile('./templates/env.txt', '.env.example')
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
const path = require('path');
const src = path.resolve(__dirname, relativeSourcePath);
if (!fs.existsSync(src)) throw new Error(`template file missing: ${src}`);
api.renderFile(relativeSourcePath, relativeTargetPath, scope);

Type guard

function isTemplateFile(baseDir, p) {
  const fs = require('fs');
  const full = require('path').resolve(baseDir, p);
  return fs.existsSync(full) && fs.statSync(full).isFile();
}

Prevention

When it happens

Trigger: api.renderFile('./tpl.txt', 'src/tpl.txt') where path.resolve(getCallerPath(), relativeSourcePath) doesn't exist — typo, file not published in the extension package, or path mistakenly given relative to the app root.

Common situations: Template file missing from the published npm package (omitted from 'files'), filename case mismatch on case-sensitive filesystems (Linux CI), or refactoring that moved/renamed template files.

Related errors


AI-assisted analysis of quasarframework/quasar@4841521b5f (2026-08-30). Data as JSON: /api/errors/53d40b5422f35f46. Report an issue: GitHub.

Appendix: source

Thrown at app-vite/lib/app-extension/api-classes/InstallAPI.js:284

    })
  }

  /**
   * Render a file from extension template into devland
   * Needs a path (to a file) relative to the path of the file where renderFile() is called
   *
   * @param {string} relativeSourcePath (file path relative to the folder from which the install script is called)
   * @param {string} relativeTargetPath (file path relative to the root of the app -- including filename!)
   * @param {object} scope (optional; rendering scope variables)
   */
  renderFile(relativeSourcePath, relativeTargetPath, scope) {
    const dir = getCallerPath(1)
    const sourcePath = path.resolve(dir, relativeSourcePath)
    const targetPath = this.resolve.app(relativeTargetPath)
    const rawCopy = !scope || Object.keys(scope).length === 0

    if (!fs.existsSync(sourcePath)) {
      this.logger.warn(
        `renderFile() - cannot locate ${relativeSourcePath}. Skipping...`
      )
      return
    }
    if (fs.lstatSync(sourcePath).isDirectory()) {
      this.logger.warn(
        `renderFile() - "${relativeSourcePath}" is a folder instead of a file. Skipping...`
      )
      return
    }

    this.#hooks.renderFiles.push({
      sourcePath,
      targetPath,
      rawCopy,
      scope,
      overwritePrompt: true
    })

View on GitHub (pinned to 4841521b5f)