diff --git a/shaker/helpers.py b/shaker/helpers.py
index a04e149..8aa577f 100644
--- a/shaker/helpers.py
+++ b/shaker/helpers.py
@@ -2,6 +2,7 @@ import logging
 import json
 import requests
 import os
+import re
 
 def get_valid_github_token(online_validation_enabled = False):
     """
@@ -97,3 +98,69 @@ def validate_github_access(response):
                     logging.error("Unknown problem checking credentials: %s" % response_message)
     
     return valid_credentials
+
+def parse_metadata(metadata):
+    """
+    Entry function to handle the metadata parsing workflow and return a metadata 
+    object which is cleaned up
+    
+    Args:
+        metadata (dictionary): Keyed salt formula dependency information
+    
+    Returns:
+        parsed_metadata (dictionary): The original metadata parsed and cleaned up
+    """
+    # Remove duplicates
+    parsed_metadata = resolve_metadata_duplicates(metadata)
+    return parsed_metadata
+    
+def resolve_metadata_duplicates(metadata):
+    """
+    Strip duplicates out of a metadata file. If we have no additional criteria, 
+    simply take the first one. Or can resolve by latest version or preferred organisation
+    if required
+
+    Args:
+        metadata (dictionary): Keyed salt formula dependency information
+
+    Returns:
+        resolved_dependencies (dictionary): The original metadata stripped of duplicates
+            If the metadata could not be resolved then we return the original args version
+    """
+    # Only start to make alterations if we have a valid metadata format
+    # Otherwise throw an exception
+
+    # If metadata is not a dictionary or does not contain
+    # a dependencies field then throw an exception
+    if not (isinstance(metadata, type({}))):
+        raise TypeError("resolve_metadata_duplicates: Metadata is not a "
+                        "dictionary but type '%s'" % (type(metadata)))
+    elif not ("dependencies" in metadata):
+        raise IndexError("resolve_metadata_duplicates: Metadata has "
+                         "no key called 'dependencies'"
+                         )
+    # Count the duplicates we find
+    count_duplicates = 0
+
+    resolved_dependency_collection = {}
+    for dependency in metadata["dependencies"]:
+        # Filter out formula name
+        org, formula = dependency.split(':')[1].split('.git')[0].split('/')
+
+        # Simply take the first formula found, ignore subsequent
+        # formulas with the same name even from different organisations
+        # Just warn, not erroring out
+        if formula not in resolved_dependency_collection:
+            resolved_dependency_collection[formula] = dependency 
+        else:
+            # Do some sort of tag resolution
+            count_duplicates += 1
+            logging.warning("resolve_metadata_duplicates: Skipping duplicate dependency %s" %(formula))
+
+    # Only alter the metadata if we need to
+    if count_duplicates > 0:
+        resolved_dependencies = resolved_dependency_collection.values()
+        metadata["dependencies"] = resolved_dependencies
+
+    return metadata
+
diff --git a/shaker/resolve_deps.py b/shaker/resolve_deps.py
index c7a205c..f8a7b45 100644
--- a/shaker/resolve_deps.py
+++ b/shaker/resolve_deps.py
@@ -131,7 +131,8 @@ def get_reqs(org_name, formula_name, constraint=None):
      # Check for successful access and any credential problems
     if helpers.validate_github_access(metadata):
         found_metadata = True
-        data = yaml.load(metadata.text)
+        # Read in the yaml metadata from body, stripping out duplicate entries
+        data = helpers.parse_metadata(yaml.load(metadata.text))
         reqs = data['dependencies'] if 'dependencies' in data and data['dependencies'] else []
     else:
         reqs = requests.get(req_url.format(org_name, formula_name,

Duplicates in metadata.yml
We don't throw an error if some idiot (me) puts duplicate lines in metadata.yml
diff --git a/tests/test_metadata_handling.py b/tests/test_metadata_handling.py
new file mode 100644
index 0000000..7723861
--- /dev/null
+++ b/tests/test_metadata_handling.py
@@ -0,0 +1,67 @@
+import unittest
+import yaml
+from shaker import helpers
+from nose.tools import raises
+
+class TestMetadataHandling(unittest.TestCase):
+
+    # Sample metadata with duplicates
+    _sample_metadata_duplicates = {
+        "dependencies": [
+            "git@github.com:test_organisation/test1-formula.git==v1.0.1",
+            "git@github.com:test_organisation/test1-formula.git==v1.0.2",
+            "git@github.com:test_organisation/test2-formula.git==v2.0.1",
+            "git@github.com:test_organisation/test3-formula.git==v3.0.1",
+            "git@github.com:test_organisation/test3-formula.git==v3.0.2"
+        ],
+        "entry": ["dummy"]
+    }
+
+    _sample_metadata_no_duplicates = {
+        "dependencies": [
+            "git@github.com:test_organisation/test1-formula.git==v1.0.1",
+            "git@github.com:test_organisation/test2-formula.git==v2.0.1",
+            "git@github.com:test_organisation/test3-formula.git==v3.0.1"
+        ],
+        "entry": ["dummy"]
+    }
+
+    def test_resolve_metadata_duplicates(self):
+        """
+        Check if we successfully remove duplicates from a sample metadata
+        """
+        original_metadata = self._sample_metadata_duplicates
+        expected_metadata = self._sample_metadata_no_duplicates
+        resolved_metadata = helpers.resolve_metadata_duplicates(original_metadata)
+
+        expected_metadata_dependencies = expected_metadata["dependencies"]
+        resolved_metadata_dependencies = resolved_metadata["dependencies"]
+        expected_metadata_entries = expected_metadata["entry"]
+        resolved_metadata_entries = resolved_metadata["entry"]
+
+        # Test dependencies found
+        for expected_metadata_dependency in expected_metadata_dependencies:
+            self.assertTrue(expected_metadata_dependency in resolved_metadata_dependencies, 
+                            "test_resolve_metadata_duplicates: dependency '%s' not found in de-duplicated metadata"
+                            % (expected_metadata_dependency))
+
+        # Test entry found
+        for expected_metadata_entry in expected_metadata_entries:
+            self.assertTrue(expected_metadata_entry in resolved_metadata_entries, 
+                            "test_resolve_metadata_duplicates: Entry '%s' not found in de-duplicated metadata"
+                            % (expected_metadata_entry))
+
+    @raises(TypeError)
+    def test_resolve_metadata_duplicates_bad_metadata_object(self):
+        """
+        Check if bad yaml metadata will throw up a TypeError.
+        """
+        # Callable with bad metadata
+        helpers.resolve_metadata_duplicates("not-a-dictionary")
+
+    @raises(IndexError)
+    def test_resolve_metadata_duplicates_metadata_missing_index(self):
+        """
+        Check if metadata with a missing index will throw an error
+        """
+        helpers.resolve_metadata_duplicates({})

pip install -e .
parse_log_pytest
requirements.txt
nose responses pytest
apt-get update apt-get install -y libgit2-dev libssh2-1-dev
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
certifi==2025.1.31
cffi==1.17.1
charset-normalizer==3.4.1
exceptiongroup==1.2.2
idna==3.10
iniconfig==2.1.0
nose==1.3.7
packaging==24.2
pluggy==1.5.0
pycparser==2.22
pygit2==1.15.1
pytest==8.3.5
PyYAML==6.0.2
requests==2.32.3
responses==0.25.7
-e git+https://github.com/ministryofjustice/salt-shaker.git@f7ab3acca99aa24b58d6d14f747c1d7b1daeac2c#egg=salt_shaker
tomli==2.2.1
urllib3==2.3.0

name: salt-shaker
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - certifi==2025.1.31
      - cffi==1.17.1
      - charset-normalizer==3.4.1
      - exceptiongroup==1.2.2
      - idna==3.10
      - iniconfig==2.1.0
      - nose==1.3.7
      - packaging==24.2
      - pluggy==1.5.0
      - pycparser==2.22
      - pygit2==1.15.1
      - pytest==8.3.5
      - pyyaml==6.0.2
      - requests==2.32.3
      - responses==0.25.7
      - tomli==2.2.1
      - urllib3==2.3.0
prefix: /opt/conda/envs/salt-shaker

tests/test_metadata_handling.py::TestMetadataHandling::test_resolve_metadata_duplicates tests/test_metadata_handling.py::TestMetadataHandling::test_resolve_metadata_duplicates_bad_metadata_object tests/test_metadata_handling.py::TestMetadataHandling::test_resolve_metadata_duplicates_metadata_missing_index
shaker/helpers.py shaker/resolve_deps.py
shaker/helpers.py shaker/resolve_deps.py