Error 404: Character Not Found

JavaScript, 228 bytes

etInterval=stInterval=seInterval=setnterval=setIterval=setInerval=setIntrval=setInteval=setInteral=setIntervl=setInterva=top=>4

setInterval
`405>(i=this.i?i:1)?alert(i++):0`///`
setInterval
`405>(i=this.i?i:1)?alert(i++):0`///`

Explanation

Evaluating code in a setInterval allows the program to continue even if there is an error. We make sure that the code passed will error out if any single character is removed. Template string syntax can be abused to call setInterval with a constant string without parentheses. Luckily, even if the template string is on the next line it still parses as a function call with such syntax.

The first issue we run into is that setInterval is a function, and thus if a character is removed and the program tries to call setInteval instead, it errors out. Of course, since there are two indentical invocations of the setInterval, we don't have to worry about it actually functioning correctly as long as we avoid the error. So, the first line defines every possible "misspelling" of setTimeout to a valid function.

The first line works by assigning all of these "misspellings" to the function top=>4. Note the ES6 syntax, this simply takes a paramater named "top" and returns 4. Why "top"? Well, the first line must never throw an error even if a character is removed. If an = is removed to make top>4, this boolean expression will be valid since top is predefined in browsers, simply yielding false. If the 4 is removed, the function body simply becomes the first setInterval segment, and the second runs unharmed.

Now, all that is left to worry about is if a ` is removed.

If removed from the beginning, setInterval simply does nothing, evaluating to itself as its own expression. Then, the rest of the second line simply runs a single iteration of the loop, letting the other setInterval fragment finish the job. If removed from the end, the remaining backtick is picked up from the end of the comment.

The newlines are placed so that removal one will not affect program behavior, but they prevent errors in the case of some character removals such as the leading backtick.


Pyth - 16 bytes

The basic idea behind this is that when you take a digit off of 404, it only makes the number smaller, so we just have to get the maximum of two 404's to ensure we have the right number. Obviously, there are a bunch more redundancies.

SSsetSS[404  404

Explanation:

SS                       First one does 1-index range, second one sorts, which is no-op 
 s                       If the e is there, this is no-op, if only t is there, it sums a one element list, which is the item
  et                     e picks last element in list, and if e is gone, then t gets you the list without the first element which is good enough when combined with s
   SS                    Sorting twice is no-op
    [                    Start list, this can't be two element because if we get rid of initial 4, the 0 becomes third element which neeeds to be captured
     404                 One of the 404's
     <space><space>404   Need two spaces for redundancy, because 404404 *is* bigger than 404

Try it online here.


Befunge-98, 37 bytes

20020xx##;;11++::''ee44**``kk@@::..;;

Try it online!

Explanation

Making radiation-hardened code in Befunge-98 isn't too bad, because you can set the "delta" (i.e. the step size of the instruction pointer) manually with x. So if set the delta to (2,0), from then on every other character is skipped and we can simply double up all commands. The tricky thing is getting 2 0 on top of the stack in a reliable way. We'll actually need 0 2 0 for the rest the program to work correctly, but we'll that for free. Here is how we do this:

20020xx

Note that each digit pushes itself, so in the full program, there will be a start 2 0 which we'll simply ignore.

Consequently, dropping either the first or second character from the program is irrelevant because we won't use those digits anyway. Likewise, removing the third character is identical to removing the second, so we don't need to worry about that either.

Let's consider what happens in the other two cases. Dropping the fourth character:

2000xx

Note the delta is set to (0,0). But this doesn't move the instruction pointer at all, so the same x is executed again immediately and this time pops the (2,0) and all is well (there are implicit zeros at the bottom of the stack for our later purposes).

Let's drop the fifth character instead:

2002xx

Now the delta gets set to (0,2). However, there is still no horizontal movement, so the IP wraps immediately back to x and again, the correct delta gets set.

From this point onward we can basically ignore the character duplication as well as this initial part because it will always be skipped:

...#;1+:'e4*`k@:.;

The ; is a sort of comment command which skips everything until the next ; is encountered. However, we jump over the first ; with # so only the part between the ; will be executed from that point onward.

1+    Increment the top of the stack.
:     Duplicate it.
'e    Push 101.
4*    Multiply by 4 to get 404.
`     Greater-than check. Pushes 1 once the top
      reaches 405, otherwise 0.
k@    Terminate the program that many times.
:.    Print a copy of the top of the stack (and a space).