Stuck on test #14 in “Build a Cargo Manifest Validator” (Lab) – validateManifest seems correct

Hi everyone,
I’m currently on day 4 stuck on test #14 of the “Build a Cargo Manifest Validator” lab.
I’ve checked multiple forum threads from the last few days (many people seem to be stuck on the same test), and I’ve compared my logic with several other solutions, but I still can’t understand why this specific test fails.

My validateManifest function seems to follow all the user stories:

  • returns “Missing” when a property is null, undefined, or absent

  • returns “Invalid” when the type or value is incorrect

  • returns an empty object {} when everything is valid

  • removes undefined properties before returning

  • handles non-object input by returning all fields as “Missing”

  • checks types before doing operations like .trim()

    Here is my full code:

    js

    function normalizeUnits(manifest) {
      const newManifest = { ...manifest };
      if (manifest.unit === "lb") {
        newManifest.weight = manifest.weight * 0.45;
        newManifest.unit = "kg";
      }
      return newManifest;
    }
    
    function validateManifest(manifest) {
      if (typeof manifest !== "object" || manifest === null || Array.isArray(manifest)) {
        return {
          containerId: "Missing",
          destination: "Missing",
          weight: "Missing",
          unit: "Missing",
          hazmat: "Missing"
        };
      }
    
      const errors = {
        containerId: undefined,
        destination: undefined,
        weight: undefined,
        unit: undefined,
        hazmat: undefined
      };
    
      if (manifest.containerId == null) {
        errors.containerId = "Missing";
      } else if (!Number.isInteger(manifest.containerId) || manifest.containerId < 1) {
        errors.containerId = "Invalid";
      }
    
      if (manifest.destination == null) {
        errors.destination = "Missing";
      } else if (typeof manifest.destination !== "string" || manifest.destination.trim() === "") {
        errors.destination = "Invalid";
      }
    
      if (manifest.weight == null) {
        errors.weight = "Missing";
      } else if (typeof manifest.weight !== "number" || Number.isNaN(manifest.weight) || manifest.weight < 0) {
        errors.weight = "Invalid";
      }
    
      if (manifest.unit == null) {
        errors.unit = "Missing";
      } else if (manifest.unit !== "kg" && manifest.unit !== "lb") {
        errors.unit = "Invalid";
      }
    
      if (manifest.hazmat == null) {
        errors.hazmat = "Missing";
      } else if (typeof manifest.hazmat !== "boolean") {
        errors.hazmat = "Invalid";
      }
    
      for (const key in errors) {
        if (errors[key] === undefined) {
          delete errors[key];
        }
      }
    
      return errors;
    }
    
    function processManifest(manifest) {
      const errors = validateManifest(manifest);
    
      if (Object.keys(errors).length > 0) {
        console.log(`Validation error: ${manifest.containerId}`);
        console.log(errors);
        return;
      }
    
      console.log(`Validation success: ${manifest.containerId}`);
    
      const normalized = normalizeUnits(manifest);
      console.log(`Total weight: ${normalized.weight} kg`);
    }
    

    If anyone has passed test #14 and can spot what I’m missing, I’d really appreciate your help.
    Thanks in advance!

Welcome to the forum @Kernela !

This seems suspect. Why are you altering a value in the manifest before you check its validity/

Happy coding!

Hi @dhess, thanks for replying!
I just realised I accidentally pasted the wrong version of my code in the previous message, sorry, I am very tired.

Here is the correct and complete version of all my functions (normalizeUnits, validateManifest, and processManifest). This is the code that is currently failing test #14:

function normalizeUnits(manifest) {
  const newManifest = { ...manifest };
  if (manifest.unit === "lb") {
    newManifest.weight = manifest.weight * 0.45;
    newManifest.unit = "kg";
  }
  return newManifest;
}

function validateManifest(manifest) {
  if (typeof manifest !== "object" || manifest === null || Array.isArray(manifest)) {
    return {
      containerId: "Missing",
      destination: "Missing",
      weight: "Missing",
      unit: "Missing",
      hazmat: "Missing"
    };
  }

  const errors = {
    containerId: undefined,
    destination: undefined,
    weight: undefined,
    unit: undefined,
    hazmat: undefined
  };

  if (manifest.containerId == null) {
    errors.containerId = "Missing";
  } else if (!Number.isInteger(manifest.containerId) || manifest.containerId < 1) {
    errors.containerId = "Invalid";
  }

  if (manifest.destination == null) {
    errors.destination = "Missing";
  } else if (typeof manifest.destination !== "string" || manifest.destination.trim() === "") {
    errors.destination = "Invalid";
  }

  if (manifest.weight == null) {
    errors.weight = "Missing";
  } else if (typeof manifest.weight !== "number" || Number.isNaN(manifest.weight) || manifest.weight < 0) {
    errors.weight = "Invalid";
  }

  if (manifest.unit == null) {
    errors.unit = "Missing";
  } else if (manifest.unit !== "kg" && manifest.unit !== "lb") {
    errors.unit = "Invalid";
  }

  if (manifest.hazmat == null) {
    errors.hazmat = "Missing";
  } else if (typeof manifest.hazmat !== "boolean") {
    errors.hazmat = "Invalid";
  }

  for (const key in errors) {
    if (errors[key] === undefined) {
      delete errors[key];
    }
  }

  return errors;
}

function processManifest(manifest) {
  const errors = validateManifest(manifest);

  if (Object.keys(errors).length > 0) {
    console.log(`Validation error: ${manifest.containerId}`);
    console.log(errors);
    return;
  }

  console.log(`Validation success: ${manifest.containerId}`);

  const normalized = normalizeUnits(manifest);
  console.log(`Total weight: ${normalized.weight} kg`);
}

If you have any idea why test #14 still fails with this version, I’d really appreciate your help!

is that the only test that’s failing?

Yes, test #14 is the only one failing. Here is exactly what I see when I run the tests:// running tests
14. If the input manifest object is not valid, your validateManifest function should return an object describing missing and/or invalid properties.
// tests completed

What happens when you test your code like this?

console.log(validateManifest({ containerId: null, destination: "Salinas", weight: 45.45, unit: "kg", hazmat: true }))

Add a console.log in there to see what containerId is when you don’t include it in the manifest.

I ran both tests:

js

console.log(validateManifest({
  containerId: null,
  destination: "Salinas",
  weight: 45.45,
  unit: "kg",
  hazmat: true
}));

and

js

console.log(validateManifest({
  destination: "Salinas",
  weight: 45.45,
  unit: "kg",
  hazmat: true
}));

Both return:

Code

{ containerId: "Missing" }

So containerId seems to be handled correctly in both cases.

I also added the console.log inside validateManifest as you suggested, and when I test the case without containerId, I get:

Code

containerId is: undefined

And validateManifest returns:

Code

{ containerId: "Missing" }

So it seems to handle both null and undefined correctly.
If that part is working as expected, maybe the issue in test #14 is happening somewhere else in the flow (possibly in processManifest or normalizeUnits). I’m still trying to figure out where exactly it breaks.

Should this return:

or something else?

When I run that test, I get:

Code

containerId is: null
{ containerId: "Missing" }

So it looks like null is being handled correctly and the function returns "Missing" as expected.

But is containerId missing?

When I run that test, I get:

Code

containerId is: null
{ containerId: "Missing" }

So yes, in this context null is treated as “Missing”, because the value is present but not valid for a containerId.

And when a value is not valid, what should be returned for that property of the manifest?

Here is a full summary of how the manifest rules work in this challenge:

  • If a property is missing (not provided) or explicitly set to null, it should be marked as:

Code

"Missing"

  • If a property exists, but the value is not valid according to the rules (wrong type, wrong format, wrong range), then it should be marked as:

Code

"Invalid"

So for containerId specifically:

  • undefined → Missing

  • null → Missing

  • "abc" → Invalid

  • -5 → Invalid

  • 3.14 → Invalid

  • 42 → valid

When I run:

js

console.log(validateManifest({
  containerId: null,
  destination: "Salinas",
  weight: 45.45,
  unit: "kg",
  hazmat: true
}));

I get:

Code

containerId is: null
{ containerId: "Missing" }

And when I omit containerId entirely, I get:

Code

containerId is: undefined
{ containerId: "Missing" }

So both null and undefined are handled as “Missing”, and invalid values are handled separately as “Invalid”.

1 Like

dhess is suggesting that a “Missing” value actually means the object doesn’t actually have the property, not that its value is nullish (null/undefined).

Regardless, this isn’t the reason your code isn’t passing the test. I copied your most recent code revision, modified the actual line of code that was causing it to fail the automated test and it passed, in spite of the issue dhess was suggesting you look at.

I don’t want to give the answer away directly, but have a look at the specifications for each object property. Read them in detail. (I actually had the same bug before I passed it earlier - it’s easily done. :sweat_smile:)

Thank you so much, @Eth0! Your hint was exactly what I needed. I went back to the properties specifications like you suggested and I finally spotted the tiny detail I had misunderstood. It was indeed one of those easy-to-miss conditions — everything is passing now.

And a big thank you to @dhess as well for the patience and all the back-and-forth yesterday. I really appreciate the help from both of you!