A `language` file set in a format extension is resolved against the wrong directory

未關閉
#15,063 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

還沒有人認領這個 Issue。

評估

難度
3/5
預估耗時
1-2 天
新手友好度
55/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
typescript
領域
cli

研究方向

Reproduce with the three-file setup in the report, then follow the stack trace. The base-directory mismatch sits between resolveExtensionPaths in src/extension/extension.ts (around L457-463), readExtensionFormat and resolveFormatsFromMetadata in src/command/render/render-contexts.ts (around L100 and L720), and resolveLanguageMetadata in src/core/language.ts (around L148-158). Done means the render succeeds, the table of contents reads "Contents from the extension", and a per-language file such as _language-fr.yml loads.

由索引模型根據 Issue 內容生成。

描述

bug extensions localization
I have
  • searched the issue tracker for similar issues
  • installed the latest version of Quarto CLI
  • formatted my issue following the Bug Reports guide
Bug description

A format extension can't point language at a translation file of its own.
Quarto looks for the file in the wrong place and stops the render, so every document that uses the format fails.
It doesn't depend on the output format: html, pdf, docx, typst, and revealjs all fail the same way.
The same strings set inline under language in _extension.yml work, so only the file form is broken.

Two parts of Quarto prepare the path, and each one assumes a different base directory:

  1. resolveExtensionPaths rewrites the paths in _extension.yml with toInputRelativePaths, so _language.yml becomes _extensions/langfile/_language.yml.
    That value is relative to the directory of the document.
  2. readExtensionFormat then calls resolveFormatsFromMetadata(extensionMetadata, extension.path, ...).
    That function takes dirname(input) as its base, and extension.path is already the extension directory, so the base ends up as the parent, _extensions/.
    resolveLanguageMetadata joins the two, which gives _extensions/_extensions/langfile/_language.yml.

The extension can't work around this with another relative path.
Step 1 rewrites any path that exists, ../_language.yml included, and step 2 then joins it to _extensions/ all the same.

This matters more now that $quarto.language.*$ exposes these strings to templates, and that custom keys reach them (#14772).
A format extension would naturally keep its own strings in a _language.yml with per-language files beside it, the same way Quarto ships its translations.
At the moment the only option is to inline them under language in _extension.yml.

Steps to reproduce

Three files.

_extensions/langfile/_extension.yml:

title: Language file
author: Example
version: 1.0.0
contributes:
  formats:
    html:
      language: _language.yml

_extensions/langfile/_language.yml:

toc-title-document: "Contents from the extension"

index.qmd:

---
title: "Language file shipped by an extension"
format: langfile-html
toc: true
---

## Section

Body.

Then:

quarto render index.qmd
Actual behavior

The render stops before Pandoc runs:

ERROR: Specified 'language' file does not exist: /path/to/project/_extensions/_extensions/langfile/_language.yml

Stack trace:
    at resolveLanguageMetadata (file:///path/to/quarto-cli/src/core/language.ts:152:13)
    at resolveFormatsFromMetadata (file:///path/to/quarto-cli/src/command/render/render-contexts.ts:116:9)
    at async readExtensionFormat (file:///path/to/quarto-cli/src/command/render/render-contexts.ts:720:23)
    at async resolveFormats (file:///path/to/quarto-cli/src/command/render/render-contexts.ts:544:31)
    at async renderContexts (file:///path/to/quarto-cli/src/command/render/render-contexts.ts:230:19)
    at async renderFileInternal (file:///path/to/quarto-cli/src/command/render/render-files.ts:448:16)

I get this error on a dev build of main at b86f98d382940bef6c65f37ea0bdfba844f19b6d, and the same one on 1.10.19, with each of these:

  • html, pdf, docx, typst, and revealjs as the base format of the extension.
  • An extension under an organisation directory inside a project (_extensions/acme/langfile/), where the path becomes _extensions/acme/_extensions/acme/langfile/_language.yml.

Setting toc-title-document inline under language in _extension.yml instead works on both versions, and the title reads "Contents from the extension".

Expected behavior

Quarto should resolve the file relative to the extension directory, as it does for template-partials and the other paths in _extension.yml.
The render should then succeed and the table of contents should read "Contents from the extension".

Per-language files beside it (_language-fr.yml) should load the same way they do for a document or project language file.

Your environment
  • IDE: Visual Studio Code
  • OS: macOS, darwin 27.0.0
Quarto check output
Quarto 99.9.9

[✓] Checking environment information...
      Quarto cache location: /Users/mcanouil/Library/Caches/quarto
      Project: none found (single-file mode)

[✓] Checking versions of quarto binary dependencies...
      Pandoc version 3.10.0: OK
      Dart Sass version 1.101.0: OK
      Deno version 2.7.14: OK
      Typst version 0.15.1: OK

[✓] Checking versions of quarto dependencies......OK

[✓] Checking Quarto installation......OK
      Version: 99.9.9
      commit: b86f98d382940bef6c65f37ea0bdfba844f19b6d
      Path: /Users/mcanouil/Projects/quarto-dev/quarto-cli/package/dist/bin

[✓] Checking tools....................OK
      TinyTeX: v2026.07
      Chrome Headless Shell: (not installed)
      VeraPDF: (not installed)

[✓] Checking LaTeX....................OK
      Using: TinyTex
      Path: /Users/mcanouil/Library/TinyTeX/bin/universal-darwin
      Version: 2026

[✓] Checking Chrome Headless....................OK
      Using: Chrome from QUARTO_CHROMIUM
      Path: /Applications/Brave Browser.app/Contents/MacOS/Brave Browser

[✓] Checking basic markdown render....OK

ℹ R version 4.6.1 (2026-06-24)
! Config '~/.Rprofile' was loaded!

[✓] Checking R installation...........OK
      Version: 4.6.1
      Path: /Library/Frameworks/R.framework/Versions/4.6/Resources
      LibPaths:
        - /Users/mcanouil/Library/R/arm64/4.6/library
        - /Library/Frameworks/R.framework/Versions/4.6/Resources/library
      knitr: 1.51
      rmarkdown: 2.31

[✓] Checking Knitr engine render......OK

[✓] Checking Python 3 installation....OK
      Version: 3.9.6
      Path: /Library/Developer/CommandLineTools/usr/bin/python3
      Jupyter: (None)

      Jupyter is not available in this Python installation.
      Install with python3 -m pip install jupyter

[✓] Checking Julia installation...
主要語言
JavaScript
星號
6.1k
分支
476
平均合併
17 小時 7 分鐘
30 天內合併 PR
112

環境準備

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

quarto-dev/quarto-cli 的其他 Issue

查看 quarto-dev/quarto-cli 的全部 Issue

相似的 Issue

更多 JavaScript Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。