Skip to content

stanc_options_to_args(quote_values = TRUE) hand-quotes values with single quotes #1263

Description

@jgabry

Discovered during work on #1262, Stage 1 of the v1.0 compilation-state work tracked in #1258. I asked Claude to write up the report below. This is an edge case unlikely to be hit by real users, but opening in case we can clean it up easily as part of v1.0.

Describe the bug

stanc_options_to_args() (R/model.R) builds the STANCFLAGS value that $compile() hands to make with quote_values = TRUE, which wraps every value except name in single quotes by hand:

paste0("--", option_name, "=", "'", option_value, "'")

Make expands that value and the shell splits it, and hand-written single quotes survive neither step in general. A value holding a ' ends the quoting early, and a $ is expanded by Make before the shell sees it. #1230 was the same defect for include paths, and #1262 fixed it there with make_shell_quote(), which single-quotes a word only when the shell could interpret something in it and doubles $ for Make. The stanc_options values were left alone in #1262 because they are not a Stage 1 item.

To Reproduce

mod <- cmdstan_model(stan_file, compile = FALSE)
mod$compile(stanc_options = list("filename-in-msg" = "it's.stan"), force_recompile = TRUE)

The direct stanc calls receive --filename-in-msg=it's.stan and succeed; the make step receives --filename-in-msg='it's.stan', the shell reads 'it' then s.stan' with an unterminated quote, and stanc never runs with the intended value.

Expected behavior

The make step receives the value the direct calls receive. Drop quote_values from stanc_options_to_args() and run make_shell_quote() over the direct vector to produce the Make vector, the way $compile() already does for the flags read from make/local. The name carve-out likely disappears with it, since a plain identifier contains nothing make_shell_quote() quotes. One round-trip test in the #1230 pattern, with a value holding a space, a quote and a dollar sign, asserting the flag stanc prints in verbose output.

Additional context

Not a regression. Same class as #820, #1227, #1230 and #1232. Found in the Codex review of #1262 (2026-09-09), which confirmed the branch did not make it worse.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions