rstudio / pins-r

Pin, Discover and Share Resources
https://pins.rstudio.com
Other
301 stars 62 forks source link

Error: C stack usage xxx is too close to the limit, with certain input to pin_write metadata parameter #824

Open marioem opened 2 months ago

marioem commented 2 months ago

The following code causes Error: C stack usage xxx is too close to the limit:

    mbm %>% pin_write(wfset_fits1, 
                      name = wfset_s1_name, 
                      description = glue::glue("{prod_name} meanlog prediction workflowsets {transf_msg} {this_rev}"),
                      metadata = list(dataset_name = DS1_df_name,
                                      dataset_version = DS1vers$version[nrow(DS1vers)],
                                      comment = fit_pin_comment,
                                      tuning_metric = opt_metric,
                                      tidymodels_version = packageVersion("tidymodels"),
                                      R_version = R.version['version.string'][[1]]),
                      versioned = T)

Guessing `type = 'rds'`Creating new version '20240412T095624Z-d6b98'Error: C stack usage  15909096 is too close to the limit

As a result no data is written to the pin, only the enclosing folder is created.

mbm is a board_folder board, located on local disk.

The problem is triggered by tidymodels_version = packageVersion("tidymodels"). I've narrowed down the issue to write_meta function (it may be in write_yaml or below).

Workaround consists in casting packageVersion result to character.

I'd suggest adding some input sanity checks before writing yaml, or casting to character user-provided input, as default.

BTW, incredibly useful package, using it all the time in my modeling workflows.

BRs,

Mariusz

juliasilge commented 2 months ago

Thanks for the report @marioem!

Here is a smaller example that shows the problem:

pins:::to_utf8(list(version = packageVersion("pins")))

The problem is that to_utf8() is recursing forever for this thing:

class(packageVersion("pins"))
#> [1] "package_version" "numeric_version"

Created on 2024-04-15 with reprex v2.1.0

juliasilge commented 2 months ago

Well, that's interesting:

is.list(packageVersion("pins"))
#> [1] TRUE
str(packageVersion("pins"))
#> Classes 'package_version', 'numeric_version'  hidden list of 1
#>  $ : int [1:3] 1 3 0

Created on 2024-04-15 with reprex v2.1.0

I think your workaround (coercing this funny object to character) is definitely the way to go for now @marioem. We do have lots of sanity checks and coercion, etc, before writing to YAML, but this particular thing is pretty weird:

x <- packageVersion("pins")
class(x)
#> [1] "package_version" "numeric_version"
class(x[[1]])
#> [1] "package_version" "numeric_version"
class(x[[1]][[1]])
#> [1] "package_version" "numeric_version"

Created on 2024-04-15 with reprex v2.1.0

It just keeps going like that!