quasarframework/quasar · warning

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

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.

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)

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.