Skip to content

fix(preview): restore --output-dir for single-file preview without _quarto.yml#14491

Merged
cderv merged 1 commit intomainfrom
fix/preview-output-dir-no-project
May 6, 2026
Merged

fix(preview): restore --output-dir for single-file preview without _quarto.yml#14491
cderv merged 1 commit intomainfrom
fix/preview-output-dir-no-project

Conversation

@cderv
Copy link
Copy Markdown
Member

@cderv cderv commented May 6, 2026

Summary

Fixes a regression introduced in v1.9.18 where quarto preview file.qmd --output-dir <dir> fails with The --output-dir flag can only be used when rendering projects. when run in a directory without _quarto.yml. This is how the Quarto VS Code extension/Positron drives single-file preview inside R packages (DESCRIPTION present, no _quarto.yml), so the bug surfaces in those workflows even though the underlying CLI behavior has nothing to do with DESCRIPTION — any quarto preview --output-dir against a single file outside a project hits it.

Fixes #14489. Reported via posit-dev/positron#13370.

Root cause

preview.ts pre-creates a singleFileProjectContext and passes it to render() as pContext. The 1.4-era synthetic-project trigger in render-shared.ts only fires when pContext is null:

if (!context && options.flags?.outputDir) {
  context = await projectContextForDirectory(path, nbContext, options);
  ...
}

Preview always supplies a context, so the trigger is skipped and the path falls through to validateDocumentRenderFlags, which throws.

quarto render foo.qmd --output-dir baz/ works because there pContext is null and the trigger fires.

Fix

Extend the trigger to also fire when pContext is a single-file context:

if (options.flags?.outputDir && (!context || context.isSingleFile)) { ... }

The discarded singleFileProjectContext cleans up through globalTempContext. The synthetic project produced by projectContextForDirectory populates files.input, so the existing isProjectInputFile arm at line 100 takes over and the path proceeds via renderProject as for any other project render.

A regression unit test exercises the exact preview pattern (tests/unit/render-shared-output-dir.test.ts).

llm-docs/synthetic-project-context.md documents the synthetic-project mechanism and the history of the two single-file context shapes (singleFileProjectContext for extensions, projectContextForDirectory for --output-dir).

Test plan

  • New unit test passes (tests/unit/render-shared-output-dir.test.ts)
  • Existing tests/smoke/render/render-output-dir.test.ts still passes
  • tests/smoke/render/render-minimal.test.ts still passes
  • Manual repro: dir without _quarto.yml + test.qmd, quarto preview test.qmd --no-browser --no-watch-inputs --output-dir <tmp> --embed-resources no longer throws and produces output

Backport

This will be backported to v1.9 separately.

…uarto.yml

When `quarto preview file.qmd --output-dir <dir>` runs in a directory
without _quarto.yml, preview pre-creates a single-file ProjectContext
and passes it to render() as pContext. The synthetic-project trigger
in render-shared only fired when context was null, bypassing it for
the preview path and surfacing the project-only-flag check.

Extend the trigger to also fire when pContext is a single-file context.
Discarded single-file context cleans up via globalTempContext.

Adds a unit test that exercises the exact preview pattern, and an
llm-docs note describing the synthetic-project mechanism + history.

Fixes #14489. Preview side of posit-dev/positron#13370.
@posit-snyk-bot
Copy link
Copy Markdown
Collaborator

posit-snyk-bot commented May 6, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@cderv cderv merged commit e1f98e2 into main May 6, 2026
92 of 93 checks passed
@cderv cderv deleted the fix/preview-output-dir-no-project branch May 6, 2026 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

quarto preview --output-dir fails when no _quarto.yml is present

2 participants