Thanks @John Polo for spotting an issue. Eventually, I realized there were other two important problems in the loop I was creating:
The subset() call was not triggering any warning so it could not work properly anyway. In order to trigger it, I had to call values() but to avoid printing the results I embedded it into invisible(). I could have called other functions too to trigger the warning, but I opted for values() believing it to be pretty fast.
You cannot assign a matrix to a SpatRaster layer. So what I did was just to subset the original SpatRaster to that specific layer and fill it with NAs.
Here it is the solution to my problem in the form of a function. Hopefully others might find it helpful, even though I am sure some spatial analysis experts could come up with a way more efficient version.
# Function to repair a possibly corrupted SpatRaster
fixspatrast <- function(exporig) {
# Create a new SpatRaster with same structure, all NA
expfix <- rast(exporig, vals = NA)
for (lyr in 1:nlyr(expfix)) {
tryCatch({
lyrdata <- subset(exporig, lyr)
invisible(values(lyrdata)) # force read (triggers warning/error if unreadable)
expfix[[lyr]] <- lyrdata
}, warning = function(w) {
message("Warning in layer ", lyr, ": ", w$message)
nalyr <- subset(exporig, lyr)
nalyr[] <- NA
names(nalyr) <- names(exporig)[lyr] # keep name
expfix[[lyr]] <- nalyr
})
}
return(expfix)
}