How to overwrite a value for a custom field?

I don’t think the problem is with the workings of the custom meta field (look into the XY problem). The issue is with the use of relative URLs, whether you realize that that is what you are doing or not.

Left empty, <a href="" target="_blank"> is by default the page you are on. Likewise, echo '<a href="'.get_post_meta($post->ID,"nada",TRUE).'" target="_blank">Hi</a>'; defaults to the page you are on if there is no ‘nada’ meta key. If there is a key, then the link ends up looking like this:

<a href="https://wordpress.stackexchange.com/questions/111552/yourkeyvalue" target="_blank">

That is a relative URL and will be converted by the browser to “the page you are on” plus “https://wordpress.stackexchange.com/questions/111552/yourkeyvalue”. There is where you are seeing things “added” together.

I am not 100% sure what you are trying to accomplish, but I think it is something like this:

$url = get_post_meta($post->ID,"source",TRUE);
if (empty($url)) {
  $url = get_permalink();
} else {
  // make an absolute URL
  $url = site_url($url);
} ?>

<a href="https://wordpress.stackexchange.com/questions/111552/<?php echo $url; ?>" target="_blank">
<?php the_post_thumbnail(); ?>
</a><?php

The only catch is the line following // make an absolute URL. I don’t know exactly what kind of information you are inserting or what kind of cleaning/validation/manipulation you need there.

If you only want to print the link if there is a source value then use this:

$url = get_post_meta($post->ID,"source",TRUE);
if (!empty($url)) { ?>
  <a href="https://wordpress.stackexchange.com/questions/111552/<?php echo $url; ?>" target="_blank">
  <?php the_post_thumbnail(); ?>
  </a><?php
} 

Your source meta value has to be an absolute URL– http://example.com/whatever. (You can probably get away with a protocol relative URL.)