Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/changelog-1.9.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,4 @@ All changes included in 1.9:
- ([#13528](https://github.com/quarto-dev/quarto-cli/pull/13528)): Adds support for table specification using nested lists and the `list-table` class.
- ([#13575](https://github.com/quarto-dev/quarto-cli/pull/13575)): Improve CPU architecture detection/reporting in macOS to allow quarto to run in virtualized environments such as OpenAI's `codex`.
- ([#13656](https://github.com/quarto-dev/quarto-cli/issues/13656)): Fix R code cells with empty `lang: ""` option producing invalid markdown class attributes.
- ([#8730](https://github.com/quarto-dev/quarto-cli/issues/8730)): Detect x64 R crashes on Windows ARM and provide helpful error message directing users to install native ARM64 R instead of showing generic "check your R installation" error.
41 changes: 40 additions & 1 deletion src/core/knitr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { rBinaryPath, resourcePath } from "./resources.ts";
import { readYamlFromString } from "./yaml.ts";
import { coerce, satisfies } from "semver/mod.ts";
import { debug } from "../deno_ral/log.ts";
import { errorOnce } from "./log.ts";

export interface KnitrCapabilities {
versionMajor: number;
Expand Down Expand Up @@ -68,6 +69,36 @@ export async function checkRBinary() {
}
}

export class WindowsArmX64RError extends Error {
constructor(msg: string) {
super(msg);
}
}

// Check for x64 R crashes on ARM Windows
// These specific error codes only occur when x64 R crashes on ARM Windows
// See: https://github.com/quarto-dev/quarto-cli/issues/8730
// https://github.com/cderv/quarto-windows-arm
function throwIfX64ROnArm(exitCode: number): void {
const isX64RCrashOnArm =
exitCode === -1073741569 || // STATUS_NOT_SUPPORTED (native ARM hardware)
exitCode === -1073741819; // STATUS_ACCESS_VIOLATION (Windows ARM VM on Mac)

if (isX64RCrashOnArm) {
throw new WindowsArmX64RError(
`R process crashed with known error code (${exitCode}).\n\n` +
"This typically indicates x64 R running on Windows 11 ARM.\n" +
"x64 R runs under emulation and is not reliable for Quarto.\n\n" +
"To fix this issue:\n" +
"1. Check your R version with: Rscript -e \"R.version$platform\"\n" +
"2. If it shows 'x86_64-w64-mingw32', you need ARM64 R\n" +
"3. Install native ARM64 R: https://blog.r-project.org/2024/04/23/r-on-64-bit-arm-windows/\n" +
"4. If needed, set QUARTO_R environment variable to point to ARM64 Rscript\n\n" +
"More context on this issue: https://github.com/quarto-dev/quarto-cli/issues/8730",
);
}
}

export async function knitrCapabilities(rBin: string | undefined) {
if (!rBin) return undefined;
try {
Expand Down Expand Up @@ -115,9 +146,17 @@ export async function knitrCapabilities(rBin: string | undefined) {
if (result.stderr) {
debug(` with stderr from R:\n${result.stderr}`);
}

throwIfX64ROnArm(result.code);

return undefined;
}
} catch (e) {
// Log x64-on-ARM errors once, then return undefined like other errors
if (e instanceof WindowsArmX64RError) {
errorOnce(e.message);
return undefined;
}
} catch {
debug(
`\n++ Error while running 'capabilities/knitr.R' ${
rBin ? "with " + rBin : ""
Expand Down
Loading