Q:

Should, in a web app using a 3-tier design pattern, one of the bottom layers provide some checking mechanism to ensure…?

I’m trying to write a web app using 4-tier design pattern ( Data Store, DAL, BLL and UI).
Among other things this app would also implement a forum. 
Suppose I want to move a thread from one forum to another. In order to do this, UI layer must pass down to other layers the ID of a thread and the ID of a forum to which I wish to move this thread ( UI would pass these parameters by calling method A in BLL layer and A would in turn call method B in DAL layer… ). 
a) Now should one of the bottom layers provide some sort of checking mechanism to ensure that the two ID arguments supplied by UI layer really represent an existing thread and an existing forum or is it the responsibility of UI layer to provide valid ID values? 
thanx

EDIT:

I would consider the ability to pass invalid IDs a bug.

Should non existing ID be considered a bug just in the case of moving a thread, or also in the case of displaying a thread. Thus when user navigates to page Showthread.aspx?ID={0}, if query string parameter ID references non existing ID, If none of the layers check for the validity of ID, then GridView simply won’t display any 

“But in this case it doesn't look like the ids are in any sort of list. If they were one could only assume that this would never happen as I assume the lists would be populated by a stored procedure or a DAL procedure that pulls all valid IDs.”

But even if user chooses IDs from a set of list, by the time it posts the page back, the DB table containing this ID could be changed in the mean time by admin or whomever?!  

A:

You should do validation at all layers of the application. I would recommend that the BLL provide a couple of functions such as 
bool ConversationThread.Exists(threadID)
bool Forum.Exists(forumThreadID)
The UI layer can then call these functions defensively to make sure that the input is valid. These functions in the BLL would probably delegate to similar functions in the DAL.
Additionally, in the DAL you should also do the same validation, and throw an exception if the validation fails, because in reality, you should do validation at all layers of the application

A:

If you have any rules about which threads can be moved to which forums, they should be in your business layer. Otherwise your errorhandling should cover the case where you attempt to handle non-existing threads or forums, as your database should give you a foreign key constraint error upon attempting to insert the invalid row.

A:

UI->BLL->DAL
UI<-BLL<-DAL
Your database is not another layer its simply a repository of the data.  What you describe is your typical 3-tier architecture.  Layers are the assemblies (dll files) while tiers are the storage mechanism (hardware).  Some people might mix those terms up but ultimately it doesn't matter.
In this case your UI calls the BLL which in turn calls the DAL.
Once you process what you need from the DAL then the DAL takes that information and passes to the BLL (Business Logic Layer) which in turn submits back to your UI.
Your UI shouldn't know anything about a valid ID, that is your UI should not touch your DAL.  Pass the ID's to the BLL and the BLL can then check if they are valid.  Some folks like to actually check inside the DAL sproc level and return some sort of flag.
bool IsValid(int forumID) {
//call the dal to get a true or false based on this
bool isValid=false;
DAL d = new DAL();
isValid = d.IsValid(forumID);
return isValid;
}

And your DAL then has a function to simply call say a sproc to return true or false if the ID exists.
bool IsValid(int forumID){
bool status;
//call sproc
status=ValueReturnedFromSproc();
return status;
}

If you are wondering how the UI handles all this it can do so by this:
BLL b = new BLL();
if (!(b.IsValid(someRandomForumID)))
  Response.Write("Sorry you've got an invalid forumID");
else
  {
    //proper forum id go ahead...
  }

In response to your edit:
If you are actually exposing the ID in the URL and allow someone to change it then your on load event needs to simply pull the ID (request parameters) and check if it is valid.  If it is show the data if it isn't redirect to a page that states "Opps it appears you are trying to access a forum / thread that does not exist".

