Problems re-Deploying Migrated shinyapps.io app

Hi! I have recently migrated a Shiny app deployed in shinyapps.io to Posit Cloud.

When deployed to shinyapps.io, I would run this code to re-deploy:

rsconnect::deployApp(
    appName = "REDACTED",
    appTitle = "REDACTED",
    appFiles = c(
        "R/",
        "inst/",
        "NAMESPACE",
        "DESCRIPTION",
        "app.R",
        ".Rbuildignore"
    ),
    account = "REDACTED",
    appId = "REDACTED",
    lint = FALSE,
    forceUpdate = TRUE,
    dependencyResolution = "library"
)

I'm trying to test a re-deploy using the same function (I was able to change the account and find the new appId) but I get errors:

I have read From your console or terminal – Posit Connect Cloud Documentation but it doesn't mention anything regarding this problem.

Any help is appreciated. Thanks in advance!

You mentioned you migrated content from shinyapps.io to Posit Cloud (I'm assuming you mean Posit Connect Cloud?)

Did you migrate the deployment record using rsconnect as described here: Migrating from shinyapps.io – Posit Connect Cloud Documentation

I see you are passing the appId in with the deploy command. I suspect you are using the shinyapps.io appId which is different than that used on Posit Connect Cloud. It shouldn't be necessary to specify that as the deployment record itself will track that.

I should mention that account will also likely be different between the two products.

You can check the existing deployment record to see what values it has:

rsconnect::deployments(appDir = "<APP_DIR>")

If its pointing at shinyapps.io, login to Connect Cloud and get the content id (its in the url) then migrate the record

rsconnect::migrateToConnectCloud(
    appPath      = "<APP_DIR>",
    contentId    = "<MIGRATED_CONTENT_ID>",
    cloudAccount = "<CONNECT_CLOUD_ACCOUNT>",
    appName      = "REDACTED"
  )

Once that is done you can deploy "as is"

rsconnect::deployApp("... path to app")

Does that sound plausible?
thanks
sam

Hi! Thanks for your answer! See my replies below :slight_smile:

As you mentioned, I meant "Posit Connect Cloud".

I migrated using the buttons in Posit Connect Cloud website:

I just clicked "Migrate" and "Finalize" after I linked my shinyapps.io acount.

I'm using the new appId set by Posit Connect Cloud (which can be found in the new URL).

I also had updated the account parameter accordingly.

Follow up question:

How would I be able to overwrite a deployment if I don't provide the appId?

EDIT (Just saw your edits to the responses):

This is what I see when I call rsconnect::deployments():

image

Try running the migrate call, then deploying again (without specifying appId or account) and see where that gets.

I did the following steps (I had deleted certain rsconnect files):

  1. Re-deployed the app to shinyapps.io using the code-approach.

  2. Migrated the app in Posit Connect Cloud, got an Id.

  3. Ran the migrate code you shared succesfully:

I'm still getting errors when I try to deploy:

I think you're hitting an edge case that shows up when a deployment has no environment variables set, on R versions older than 4.2.0. It's something we'll fix in rsconnect, but a release will take a little time.

In the meantime, could you try running the deploy under R 4.2.0 or newer (e.g. 4.5.2)? I wasn't able to reproduce the error on that version, so I want to see if it unblocks you for now. If you can also share the R version you're currently seeing the error on (R.version.string), that'll help us confirm and close this out.

Hi! Indeed, that seems to be the issue here. After running the code below (developed by Claude Code) I was able to overcome that error (I got a new one, but in this case, it is something that is on my end to fix because it's related to package versions). I will leave the code below in case is helpful in any way :slight_smile:

# Workaround for a bug in rsconnect 1.11.0 (current CRAN release as of
# 2026-08-25; still unfixed/unreported upstream as of this writing) that
# breaks deploying/re-deploying to Posit Connect Cloud whenever the
# deployment has no `envVars` configured:
#
#   Error in mapply(FUN = f, ..., SIMPLIFY = FALSE) :
#     zero-length inputs cannot be mixed with those of non-zero length
#
# Root cause
# ----------
# rsconnect:::connectCloudClient()'s createContent() and updateContent()
# closures build the "secrets" payload sent to Connect Cloud like this:
#
#   secrets <- unname(Map(function(name, value) list(name = name, value = value),
#                          envVars, Sys.getenv(envVars)))
#
# When `envVars` is NULL/character(0) (i.e. no envVars configured for the
# app -- true for any fresh deploy/migration that never passed `envVars =`
# to deployApp()), `Sys.getenv(NULL)` does NOT return character(0). It
# treats a NULL/empty filter as "no filter" and returns *every*
# environment variable in the R session instead. Map()/mapply() then gets
# one zero-length argument and one 70+-length argument mixed together,
# which errors out with the message above.
#
# Fix
# ---
# Redefine connectCloudClient() in the rsconnect namespace (for this R
# session only -- nothing is written to disk or to the installed package)
# so both call sites route through a small helper that short-circuits to
# character(0) when envVars is empty, instead of falling through to the
# buggy Sys.getenv(NULL) behavior.
#
# Usage: source this file once, before calling rsconnect::deployApp() /
# rsconnect::deploySite() for a Posit Connect Cloud target. See
# dev/03_deploy.R.

patch_rsconnect_envvars_bug <- function() {
    if (!requireNamespace("rsconnect", quietly = TRUE)) {
        stop("rsconnect is not installed.")
    }

    ns <- asNamespace("rsconnect")
    orig <- get("connectCloudClient", envir = ns)

    body_txt <- paste(deparse(body(orig)), collapse = "\n")

    marker <- "rsconnectEnvVarsPatch_safeGetenv(envVars)"
    n_marker <- length(gregexpr(marker, body_txt, fixed = TRUE)[[1]])
    if (n_marker == 1 && gregexpr(marker, body_txt, fixed = TRUE)[[1]][1] == -1L) {
        n_marker <- 0
    }
    if (n_marker == 2) {
        # Already patched earlier in this session (e.g. this file was
        # source()d more than once) -- nothing to do.
        message(
            "[patch] rsconnect::connectCloudClient() already patched for ",
            "this session; skipping."
        )
        return(invisible(TRUE))
    }

    target <- "Sys.getenv(envVars)"
    n <- length(gregexpr(target, body_txt, fixed = TRUE)[[1]])
    if (n == 1 && gregexpr(target, body_txt, fixed = TRUE)[[1]][1] == -1L) {
        n <- 0
    }

    if (n != 2) {
        stop(
            "patch_rsconnect_envvars_bug(): expected to find 2 occurrences ",
            "of `Sys.getenv(envVars)` inside rsconnect:::connectCloudClient() ",
            "(one in createContent(), one in updateContent()), but found ", n,
            ". The installed rsconnect internals may have changed since this ",
            "patch was written (installed version: ",
            as.character(utils::packageVersion("rsconnect")), "). ",
            "Skipping the patch rather than risk silently breaking deployment -- ",
            "check https://github.com/rstudio/rsconnect for a real fix first."
        )
    }

    patched_body_txt <- gsub(
        target,
        "rsconnectEnvVarsPatch_safeGetenv(envVars)",
        body_txt,
        fixed = TRUE
    )
    new_body <- parse(text = patched_body_txt)[[1]]

    patched <- orig
    body(patched) <- new_body

    patch_env <- new.env(parent = environment(orig))
    patch_env$rsconnectEnvVarsPatch_safeGetenv <- function(x) {
        if (length(x) == 0) character(0) else Sys.getenv(x)
    }
    environment(patched) <- patch_env

    assignInNamespace("connectCloudClient", patched, ns = ns)

    message(
        "[patch] rsconnect::connectCloudClient() patched for this session ",
        "to fix the 'zero-length inputs cannot be mixed' bug when envVars ",
        "is empty (see dev/patch_rsconnect_envvars_bug.R)."
    )

    invisible(TRUE)
}

patch_rsconnect_envvars_bug()