I’ve discovered something that might be a bug in some way.

In one of our web applications, one of the developers wrote a user control (ASCX). The ASCX file contained a DIV with the “runat=server” attribute named (just of the sake of the sample) “X”. The ASCX.cs file contained another property called “x” (mind the case change!).

Since the compiler is case sensitive, there was no problem with this and the whole thing compiled and run, specifically it run from Visual Studio while debugging, the problem started when we precompiled the application.

In our build process, we precompile the web applications using the ASP.NET Compiler (through MSBuild, of course ๐Ÿ˜‰ ) and since there was no compilation problem, everything went fine and the build succeeded.

We put the new build in a dev machine and started working with it. When we reached a page that used that control we got the “Ambiguous match found” exception. After searching for it in the newsgroups I found that it is a reflection related problem, so I fired up my faithful WinDbg and dived in.

I attached to the ASP.NET worker process and it broke in when the exception was thrown. I looked at the call stack (using !clrstack) and saw a call to “System.RuntimeType.GetField”, a reflection function used to get a field of an object.

OS Thread Id: 0xf38 (14)
ESP EIP
019eecb0 77e55dea [HelperMethodFrame: 019eecb0]
019eed54 79617ef1 System.RuntimeType.GetField(System.String, System.Reflection.BindingFlags
.
.
.

I run “dds 019eed54” (this address is the address of the stack frame) to see what’s on the stack and get the addresses/values of the two parameters in the function.

019eed54 0263588c
019eed58 00000001

The first two lines (shown above) contains the addresses/values (depending on the type and number of parameters passed to the function, in our case we have only two) of the function. The second column contains the addresses/values. In our case, since the first parameter is a string, the value 0263588c is actually the address of a string, so I used !dumpobject to see its value and saw that it was “x”.

The second parameter is an enumeration, so the value represents the integer value of that enum flag. I looked in Reflector and saw that the value 1 belongs to BindingFlags.IgnoreCase.

At that point I still didn’t figure out the problem, so I went back to reflector and took a look at the precompiled assembly that this code was compiled into and then saw that I had two protected fields, one named “X” and one named “x”.

Bingo! that’s the problem, staring me back from the screen.

To sum things up, while this code is correct compiler-wise (two parameters with the same characters but different casing are two different parameters), the implementation that tries to access some of it uses a case insensitive reflection search, which causes the bug.

Until I get more information from Microsoft, I suggest making sure in any ASP.NET application that is precompiled to avoid having the same names with different casing to variables in the ASPX/ASCX page and its code behind.

  • Benni B

    I searched so long, just to find the right answer here….
    Not as always mentions some defined types in designer.cs-FIle (mine was emopy) and the code-behind file…
    My Example (“HyperLinkAccount” and “HyperlinkAccount”)

    Thanks a lot, Eran. Great job!

  • Hey Benni B,

    I’m always glad to hear that someone benefited from the troubles I had. In this case I even found the exact cause which is even better ๐Ÿ˜‰

    I happy to hear this actually helped you solve your problem.

    Eran

  • Anonymous

    Thank you for the help. I’d also like to point out that if one of your controls in your .ascx is named the same as a variable in your .ascx.vb (as was my problem) it will fail the same way.

  • Thanks for the input.

  • Anonymous

    HI..

    I have downloaded Win.. debugger and trying to attached asp_net_wp.exe process but am not able to figure out which field is duplicate. Would be glad if u could guide as how to use the tools that u used to figure out.

  • Well.. basically, there is a bit of a faster way of finding this than what I’ve described.

    First, you need to attach WinDbg to the ASP.NET worker process.

    Continue to run your application and when this error occurs, WinDbg should break-in due to the exception.

    When that happens, run !clrstack -p.
    This should show you the managed call stack and the addresses of all the passed parameters to each function.

    Since the exception usually happens in the System.RuntimeType.GetField function, you should take the address of the first parameter (which is the name of the field we are looking for) and run !do 0xXXXXXX where 0xXXXXXX is the address of the string that should contain the name of the field that is probably duplicated.

    If you need further help with WinDbg to set symbols and load the SOS extension, look at previous posts here.

  • Anonymous

    thank you, thank you, thanks a lot!!!!

  • You are welcome!

  • Rich Armstrong

    Thanks! Saved us lots of time. One more thing of note: it doesn’t seem to matter that the two similarly named fields both be protected. I changed one of mine to private — it no longer needed the protected scope anyway — but that didn’t help. Only by giving them different names did the page work.

  • Kipp

    I tried your suggestion on using WinDbg to help find out exactly which variable is a duplicate but after attaching to the w3wp.exe process and then getting the “Ambiguous match found” exception to happen, windbg doesn’t break. Could there be something I’m doing wrong with WinDbg?

    Thanks

  • David

    I couldn’t figure out the windbg, but the comment about using reflector helped a lot! It was easy to see the offending variables. Just download the .NET Reflector from the web. It’s pretty easy to figure out.

  • Kipp

    Thanks for the reminder of using .NET Reflector as that was able to help me see the offending variable easier than just going through the .aspx and .aspx.cs file looking for duplicates. With Reflector the two variable were right next to each other and it was obvious where the problem was.

  • Anonymous

    Thanks a lot, it saved me hours!!!

  • You are welcome. It’s always fun to see that I could actually save time ๐Ÿ™‚

  • Paul Robinson

    Fabulous – I followed your post and fixed by problem. A bit more useful than the usual group replies of ‘have you applied the latest fixes’ or ‘look for more information at microsoft.com’. Well done!

  • Paul,

    I’m glad it helped you. This is the kind of bug that can cost you lots of time and hours figuring out just because the error is so… well… ambiguous ๐Ÿ™‚

  • Anonymous

    Thanks guys – my first .net 2005 web application, and the first line of code !
    Been writting 2003 apps for 2 years no problems.

    Downloaded Reflector – pointed it at my app, and hey presto – Job Done.

    Thanks as per the other comments for not sending me off on a wild goose chase.

    Great Blog.

  • I’m glad to hear that my blog really helps people.

    After all, that’s the reason I’ve started it in the first place ๐Ÿ™‚

  • Anonymous

    Another vote of thanks from me. Your blog, and the hint to use reflector, saved me much frustration.
    Thanks for taking time to post this.

    Simon

  • Matthew

    You are awesome. Saved me a ton of time!

  • You are welcome, Matthew ๐Ÿ™‚

  • Mohit

    Thanks alot.
    It really worked and helped me in fixing this setup issue.
    Really technical finding.
    Great job!!!!

  • Mohit, you are welcome! ๐Ÿ™‚

  • Peter

    Thanks Eran, your post helped a lot. I even wrote a short blog post about it and referred to you so that even more people may find this.

  • Peter, you are more than welcome and thanks for linking back here!

  • Pingback: Enabling WinDbg to break on CLR Exceptions » Advanced .NET Debugging()

  • Pingback: ASP.NET Compiler assumptions and a possible bug » Advanced .NET Debugging()

  • Pingback: Managed Call Stack with Parameters » Advanced .NET Debugging()

  • I had the same nasty error after moving a project from .NET 1.1 to .NET 2.0 I found your blog, and tried to catch the error with the WinDbg, but maybe because I am bot so used to it, I couldn’t.
    But, I found the problem with the VS.NET 2005 debbuger, so if someone else is having dificulties with WinDbg it could try this:
    Before starting your WebApp choose menu Debug->Exceptions and in the window check Common Language runtime exceptions. Open the aspx page that has this exception and start debugging from there (I used the internal ASP.NET WebDevelopment server). After breaking several times for some other exceptions I finally got the fameous “Ambiguous match found” . And it was the very same method (System.RuntimeType.GetField) that has the problem. And just before that one in the call stack was a call to System.Web.UI.Util.GetNonPrivateFieldType that showed me the field that has the problem. It was the same control defined twice in the same file (few lines distance from eachother), but with a different case in one letter.

  • Goran, thanks for sharing this information!

    When I get some more time I’ll write a post with these details just so everyone will see it and benefit from it.

    Thanks again!

  • Pingback: Sasha Sydoruk » Blog Archive » “Ambiguous match found” in a Web Control - a Possible Bug()

  • Tolga Guler

    thanks for sharing.

  • You are welcome.

  • vlad

    This post is 2 years old, but still very useful.
    Thanks Eran, you saved me a lot of time, I solved the problem in a couple of minutes (tbFillerId tbFillerID).
    Strange thing is that it worked until yesterday and today it crashed without someone changing anything.

    Good job and thanks for sharing!

  • Vlad, you are welcome ๐Ÿ™‚

  • Manohar

    The easiest way to find the case mismatches is to convert to web applicaton on that particular page, so VS.NET designer will give you the lead! ๐Ÿ™‚

    Thanks!
    Manohar

  • anie

    thanks a lot!

  • Marc

    In my case http://forums.asp.net/p/1003960/1788838.aspx helped. The page contained Page attribute “Codebehind” (instead of “CodeBehind”) and the conversion to a Web Application project had left this behind, i.e. it had not changed it to CodeFile.

  • Dusko

    I was getting the same message in .NET 1.x when the collection had multiple indexers (one with int and another with string index).
    This is just for record, to testify that, if nothing else, the message itself is ambiguous :).

  • Peter

    This is a jewel of a post. After reading this I was able to identify and fix my problem within minutes and I know that this is the very type of problem a person could spend days trying to figure out!

    Thanks so much!!

  • austin

    A case mismatch in the ascx or aspx page is the cause. I was able to use the object browser to find these within visual studio. the .NET reflector is not necessary.

    No thanks to Microsoft, thanks to everyone else!

  • You can download a custom build task to catch this at compile time:
    http://www.onpreinit.com/2009/09/ambiguous-match-found_30.html

  • Pingback: Ambiguous match found - Peter Johnson's Blog()

  • Thanks a lot this solved the problem.

  • Javier Regusci

    Great post Eran! It really solved the issue.
    Thanks!

  • Thank you for the suggestion what u had given above Eran Sandler.

    I got solved my application problem from your Good tips

    Thank You

  • Mohammed Imtiaz

    Hi Eran…

    Thx a lot i was facing the same issue and I was trying to resolve that from last 32 hrs.. Now i could resolve it easily … I have used a control name as variable name

    Issue diaognised
    asp:Label ID=”Projectid” and i had a varibale called “Projectid” in teh code behind….

  • Ashish

    Great post Eran! I could solve my problem within minutes… Otherwise this could have taken a quite enough time to work around. Thanks a lot. Keep the great work up! ๐Ÿ™‚

    Just a note, as in my case the problem was between: LinkbuttonCancel & LinkButtonCancel, and to find this I did not use the reflector or WinDbg. I simply tried with deleting my *.designer.cs file of the page giving this exception and then I right clicked the same page’s aspx file and used the option “Convert to web application” (after deleting designer.cs file you would see this option). This option creates designer file for you and while creating it would notice the difference between the ambiguous fields and an alert would come like:

    “Generation of designer file failed: Control LinkbuttonCancel conflicts with field LinkButtonCancel of a different case. Declaring both fields will result in an ASP.NET error.”
    And this is what I was looking for….

  • Hai

    Thanks Eran,

    Your post in 2006 still help me out of the problem when I’m converting my ASP.NET project from 1.1 to 4.0

    It seems that MS does not fix this issue ?

    Once again, thanks a lot.

  • Yes, the issue is still not fixed in .NET Framework 4.0 ! Thank you for this blog post!!