Sys.ArgumentException: Value must not be null for Controls and Behaviors

I was going thru some pages for my current project today when I ran into the said error "Sys.ArgumentException: Value must not be null for Controls and Behaviors". It was the first time I've encountered it and since it was working the last time I browsed it I didn't have a clue what was causing it so had to dig around. [more]

I have tested the page though I have to admit that not thoroughly (yeah I know, don't check in not well tested code) and there was no automated UI tests for it, took me sometime to stop the cause. I had to consider what applications I installed on my machine recently or other changes.

After some digging it turns out that it is related to a modalPopupExtender (part of AJAXControlToolkit) in the page.

Moving on, the extender's TargetControlID was set to let's say "linkAddItem" control.

Now, the catch is that recently I added an inline condition (ok, not really sure what is the right term for this but something like the one below):

<% if(MyCondition) { %>

<asp:LinkButton ID="linkAddItem" (definition here…. plus some other text) 

<% } %> 

So as you might have guessed, the page was looking for "linkAddItem" but in case MyCondition is true, it would not be rendered thus causing the error. I had read somewhere that if you have the TargetControl's (eg. linkAddItem) Visible attribute equals to "false", the AJAX control toolkit code would be able to detect with no problems. But not this one. The "Valu" mentioned in the error is likely the TargetControlID or at least related to it. You could verify by debugging the client script if this wouldn't solve the problem but fortunately enough not to go that far.

To cut this short story even shorter, my work-around was to instead have that block wrapped inside a panel (<asp:Panel…) and on Page PreRender, set the Panel.Visible = MyCondition. To simplify you could set just the control (eg. linkAddItem) Visibility but since there are other controls in that block, in my case the panel would be good.

I believe you can also set Visible='<%= MyCondition %>' of the panel in the ASPX page rather than at runtime/code for as long as you have the Page databound. : this.DataBind(); (but be careful, this is recursive and would rebind all other controls in your page you have bound previously).

Next time you run into this error, it is likely that one of the possible suspect is control visibility.