Shiny selectInput depending on validated reactive does not pass on validation error

You can get the behaviour you're looking for by replacing your renderTable() with the following:

  output$filteredTable <- renderTable({
    req(availableCars())
    cars[name %in% input$selectCar]
  })

As noted in the comments, my suspicion is that when the validation error gets passed on, it stops any downstream calculations and therefore input$selectCar doesn't get updated and the table continues to show the last selection. Using req() gets the app to check for the current value of availableCars() which then passes the validation message and updates the table.

I know this doesn't answer your question exactly, but hopefully it provides a useful workaround.


For completeness, per my comment on the other answer, strictly speaking you cannot have a validation message propagate to an input (in uiOutput or otherwise). As quoted from the article, validation propagates to reactive expressions and observers. In the language of reactivity (see this article), these are reactive conductors and reactive endpoints, respectively. This means they can take on a reactive dependency. Reactive conductors can also be used to create a reactive dependency. input is a reactive source. Reactive sources can be used to create a reactive dependency, but strictly speaking can't take on a reactive dependency (technically renderUI is actually making output$uiOutCars have the reactive dependency not input$selectCar)

All this being said, here is another workaround. It creates a pseudo-input which is a reactive expression (i.e. will have validation messages propagate through).

library(shiny)
library(data.table)

cars <- data.table(mtcars, keep.rownames = T )
setnames(cars, "rn", "name")

ui <- fluidPage(
  selectInput("cyl", "Cyl", c(4, 12)),
  uiOutput("uiOutCars"),
  h4("Filtered Table"),
  tableOutput("filteredTable")
)

server <- function(input, output, session) {

  availableCars <- reactive({
    choices <- cars[cyl == input$cyl, name]
    validate(need(try(length(choices) > 0),
                  "No cars with this cyl!"))
    choices

  })


  output$uiOutCars <- renderUI({
    selectInput(inputId = "selectCar", 
                label = "Car", 
                choices = availableCars(),
                selected = "Merc 230")
  })

  pseudoSelectCar <- reactive(
    {

      availableCars()
      # include other dependencies here
      input$selectCar

    })

  output$filteredTable <- renderTable({
    req(pseudoSelectCar()) # prevent warning on initialization
    cars[name == pseudoSelectCar()]
  })


}

The idea is that as the expression for the the pseudo input is re-evaluated, if any of the dependencies fail validation, they will short-circuit the "input" evaluation as well. Otherwise, the pseudo input is just equal to the input value.

The downside is you do have to explicitly list all your dependencies for input$selectCar in the definition of pseudoSelectCar. The upside is you just have to do this in one place and you can use pseudoSelectCar everywhere else in your code where you would have otherwise used input$selectCar