Getting 400 status code when creating new record with model reference - what data am I missing?

Building a MERN app and having issues with form submission

I’m working on a full stack project using MongoDB, Express, React, and Node. I have two models where one references the other, but when I submit my form to create a new record, I keep getting a 400 error.

My form component:

export default function CreateItemForm({handleNewItem, typesList}) {
    const [itemData, setItemData] = useState({
      title: "",
      photos: [],
      type: {typesList},
      cost: 0,
      details: ""
    });
   
    function updateField (event) {
      setItemData({...itemData, [event.target.name]: event.target.value });
    }

    async function submitItem(event) {
        event.preventDefault();
        handleNewItem(itemData);
        setItemData({
            title: "",
            photos: [],
            type: {typesList},
            cost: 0,
            details: ""
          });
      }
  
    return (
      <div>
        <h2>Create New Item</h2>
        <form onSubmit={submitItem}>
        <label>Title</label>
          <input
              name="title"
              type="text"
              value={itemData.title}
              onChange={updateField}
              required 
          />
        <label>Photos</label>
          <input
              name="photos"
              type="text"
              value={itemData.photos}
              onChange={updateField}
              required 
          />
        <label>Type</label>
          <select 
              name="type" 
              value={itemData.type}
              onChange={updateField}>
            {typesList.map ((type, index) => (
              <option key={index} value={type}>{type}</option>
            ))}
          </select>
        <label>Cost</label>
          <input
              name="cost"
              type="number"
              value={itemData.cost}
              onChange={updateField}
              required 
          />
        <label>Details</label>
          <input
              name="details"
              type="text"
              value={itemData.details}
              onChange={updateField}
              required 
          />
          <button type="submit">Create Item</button>
        </form>
      </div>
    );
  }

Main schema (trying to create):

const Schema = require('mongoose').Schema;

const itemSchema = new Schema({
    title: { type: String, required: true },
    photos: [{ type: String, required: true }],
    type: {type: Schema.Types.ObjectId, ref: 'ItemType'},
    cost: { type: Number, required: true },
    details: { type: String }
  }, {
    timestamps: true
  });
  
  module.exports = itemSchema;

Referenced schema:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const itemTypeSchema = new Schema({
  title: { type: String, required: true },
  order: Number
}, {
  timestamps: true
});

module.exports = mongoose.model('ItemType', itemTypeSchema);

Controller function:

async function addNew(req, res) {
  try {
    const newItem = await Item.create(req.body);
    res.json(newItem);
  } catch (error) {
    res.status(400).json(error);
  }
}

What am I doing wrong with the reference? The form sends data but the server throws 400 error. Any ideas what I’m missing?

what’s in your typesList? are those ObjectId strings or just title values from ItemType documents? also, have you checked the network tab to see the actual payload when you submit? that’ll show you what’s breaking validation.

Yeah, the problem’s with your type field handling. You’re passing entire objects when Mongoose only wants the ObjectId string. Also, check what’s actually in typesList - if it’s just strings, you’ll need to query the ItemType documents first to grab their _id values for your dropdown.

Your problem is with the type field in your form state. You’re setting it as type: {typesList} which wraps it in an object, but your schema wants a string that converts to an ObjectId. Also, you’re initializing photos as an array but binding it to a text input - that’ll cause type mismatches.

Here’s the fix: change your initial state to type: "" instead of type: {typesList}. Make sure your select dropdown passes the actual ObjectId value, not the display text. For photos, decide if you want a single string (one photo) or proper array handling (multiple photos). You’re getting that 400 error because MongoDB’s validation fails when it gets the wrong data types.