# Problem with composite keys - Expected id to be a string or number, received null

**URL:** <https://community.forestadmin.com/t/problem-with-composite-keys-expected-id-to-be-a-string-or-number-received-null/3123>\
**Category:** Help me!\
**Tags:** setup\
**Created:** [August 17, 2021, 8:41pm UTC](https://community.forestadmin.com/t/problem-with-composite-keys-expected-id-to-be-a-string-or-number-received-null/3123 "2021-08-17T20:41:35Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Paul\_Vidal](https://dub1.discourse-cdn.com/flex013/user_avatar/community.forestadmin.com/paul_vidal/32/2897_2.png) [@Paul\_Vidal](https://community.forestadmin.com/u/Paul_Vidal)\
**Post date:** [August 17, 2021, 8:41pm UTC](https://community.forestadmin.com/t/problem-with-composite-keys-expected-id-to-be-a-string-or-number-received-null/3123/1 "2021-08-17T20:41:35Z")

</div>

Hey there, I stubbling against an annoying problem I cannot manage to solve… Thank you for your help 🙂

## Expected behavior

I have 2 models, one is a `Proposal` that represents a contract, the other a `Proposal Member` representing a member assigned to the proposal/contract.

A proposal can have multiple proposal member, but a proposal member belong to only 1 proposal (`Proposal Member` uses a composite key based on the `memberId` and the `proposalId`).

Below are the models generated by Forest admin at setup:

**Proposal model**

```javascript
// This model was generated by Forest CLI. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  // This section contains the fields of your model, mapped to your table's columns.
  // Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
  const Proposal = sequelize.define(
    'proposal',
    {
      text: {
        type: DataTypes.STRING,
        allowNull: false,
      },
      createdAt: {
        type: DataTypes.DATE,
        defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
      },
      updatedAt: {
        type: DataTypes.DATE,
      },
      paymentOption: {
        type: DataTypes.ENUM('MILESTONES', 'PAY_AS_YOU_GO'),
        allowNull: false,
      },
      platformPercentage: {
        type: DataTypes.INTEGER,
        defaultValue: 5,
        allowNull: false,
      },
      vat: {
        type: DataTypes.INTEGER,
        defaultValue: 20,
        allowNull: false,
      },
    },
    {
      tableName: 'Proposal',
      schema: process.env.DATABASE_SCHEMA,
    }
  );

  // This section contains the relationships for this model. See: https://docs.forestadmin.com/documentation/v/v6/reference-guide/relationships#adding-relationships.
  Proposal.associate = (models) => {
    Proposal.belongsTo(models.opportunity, {
      foreignKey: {
        name: 'opportunityIdKey',
        field: 'opportunityId',
      },
      as: 'opportunity',
    });
    Proposal.hasMany(models.proposalMember, {
      foreignKey: {
        name: 'proposalIdKey',
        field: 'proposalId',
      },
      as: 'proposalProposalMembers',
    });
    Proposal.hasMany(models.proposalMilestone, {
      foreignKey: {
        name: 'proposalIdKey',
        field: 'proposalId',
      },
      as: 'proposalProposalMilestones',
    });
  };

  return Proposal;
};

```

**Proposal member model**

```javascript
// This model was generated by Forest CLI. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  // This section contains the fields of your model, mapped to your table's columns.
  // Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
  const ProposalMember = sequelize.define(
    'proposalMember',
    {
      proposalId: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        allowNull: false,
      },
      memberId: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        allowNull: false,
      },
      title: {
        type: DataTypes.STRING,
        allowNull: false,
      },
      description: {
        type: DataTypes.STRING,
        allowNull: false,
      },
      isLead: {
        type: DataTypes.BOOLEAN,
        defaultValue: false,
        allowNull: false,
      },
      rate: {
        type: DataTypes.INTEGER,
        allowNull: false,
      },
      unit: {
        type: DataTypes.ENUM('DAYS', 'HOURS'),
      },
      quantity: {
        type: DataTypes.INTEGER,
      },
      allocation: {
        type: DataTypes.INTEGER,
      },
    },
    {
      tableName: 'ProposalMember',
      timestamps: false,
      schema: process.env.DATABASE_SCHEMA,
    }
  );

  // This section contains the relationships for this model. See: https://docs.forestadmin.com/documentation/v/v6/reference-guide/relationships#adding-relationships.
  ProposalMember.associate = (models) => {
    ProposalMember.belongsTo(models.member, {
      foreignKey: {
        name: 'memberIdKey',
        field: 'memberId',
      },
      as: 'member',
    });
    ProposalMember.belongsTo(models.proposal, {
      foreignKey: {
        name: 'proposalIdKey',
        field: 'proposalId',
      },
      as: 'proposal',
    });
  };

  return ProposalMember;
};

```

## Actual behavior

What I see is:

- I can visualise both collections idependently
- From a proposal member, I can see the link to a proposal

BUT

When I click on `Details` for a `Proposal` and click on the `Proposal proposal member` relation (basically when I look for the members for a proposal using relationship on a field),

 ![Screenshot 2021-08-17 at 22.37.45](https://europe1.discourse-cdn.com/flex013/uploads/forest/original/2X/c/c24f620469f50a20213dfa4deb991734f1b923bc.png)

I get a

```javascript
Cannot reach your data

Your server may be down or your database connection broken.

```

What I see is that the request has returned form the server successfully

```javascript
{
"data":[
{"type":"proposalMember",
"attributes":{"proposalId":1,"memberId":2,"title":"Paul the engineer","description":"description","isLead":false,"rate":20,"unit":"DAYS","quantity":20,"allocation":30},
"relationships":{
"member":{"data":{"type":"member","id":"2"},"links":{"related":{"href":"/forest/proposalMember/undefined/relationships/member"}}},
"proposal":{"data":{"type":"proposal","id":"1"},"links":{"related":{"href":"/forest/proposalMember/undefined/relationships/proposal"}}}}
},
],
"included":[
{"type":"member","id":"2","attributes":{"id":2}},
{"type":"proposal","id":"1","attributes":{"id":1},"relationships":{}}
]}

```

And note I can export the 2 proposals in CSV by clikcing on Action and all works. I also see the 2 records are available for search (look at the `Search within 2 proposal proposal ...` at the top right)

But I get on the console

```javascript
[forest] 🌳🌳🌳 Unexpected error in the list view: Error: Expected id to be a string or number, received null
    at i (vendor-5274ce00880a892114c98442cc88aca6.js:14353)
    at l.h._load (vendor-5274ce00880a892114c98442cc88aca6.js:14776)
    at l.h._pushInternalModel (vendor-5274ce00880a892114c98442cc88aca6.js:14786)
    at vendor-5274ce00880a892114c98442cc88aca6.js:14784
    at e.n._run (vendor-5274ce00880a892114c98442cc88aca6.js:5357)
    at e.n._join (vendor-5274ce00880a892114c98442cc88aca6.js:5356)
    at e.n.join (vendor-5274ce00880a892114c98442cc88aca6.js:5322)
    at l.h._push (vendor-5274ce00880a892114c98442cc88aca6.js:14780)
    at vendor-5274ce00880a892114c98442cc88aca6.js:14732
    at b (vendor-5274ce00880a892114c98442cc88aca6.js:5765)
    at v (vendor-5274ce00880a892114c98442cc88aca6.js:5763)
    at t.invoke (vendor-5274ce00880a892114c98442cc88aca6.js:5286)
    at e.t.flush (vendor-5274ce00880a892114c98442cc88aca6.js:5278)
    at e.t.flush (vendor-5274ce00880a892114c98442cc88aca6.js:5292)
    at e.n._end (vendor-5274ce00880a892114c98442cc88aca6.js:5355)
    at _boundAutorunEnd (vendor-5274ce00880a892114c98442cc88aca6.js:5306)

```

My intuition is I am missing an id field on what is returned by the requests, but I don’t understand why one is required or how to solve this.

Thank you 🙇‍♂️

## Context

Please provide any relevant information about your setup.

- Package Version:
- Express Version: ~4.17.1
- Sequelize Version: ^8.0.0
- Database Dialect: Postgresql
- Database Version: PostgreSQL 13.3
- Project Name: Collective.work

---

<div class="post-metadata">

**Author:** ![anon39848301](https://avatars.discourse-cdn.com/v4/letter/a/b9e5f3/32.png) [@anon39848301](https://community.forestadmin.com/u/anon39848301)\
**Post date:** [August 18, 2021, 9:05am UTC](https://community.forestadmin.com/t/problem-with-composite-keys-expected-id-to-be-a-string-or-number-received-null/3123/2 "2021-08-18T09:05:19Z")

</div>

Hi @Paul_Vidal, and welcome to our community 👋

I tried on my end with a similar setup and I’m totally able to reproduce.  
I’ll open a ticket on our end for this issue.

The easiest workaround here would be to add an `id` column, or to override the route to add a precomputed id field. It is a far from perfect solution though.

Sorry for the inconvenience

Sorry for the inconvenience.

---

<div class="post-metadata">

**Author:** ![Paul\_Vidal](https://dub1.discourse-cdn.com/flex013/user_avatar/community.forestadmin.com/paul_vidal/32/2897_2.png) [@Paul\_Vidal](https://community.forestadmin.com/u/Paul_Vidal)\
**Post date:** [August 18, 2021, 9:23am UTC](https://community.forestadmin.com/t/problem-with-composite-keys-expected-id-to-be-a-string-or-number-received-null/3123/3 "2021-08-18T09:23:50Z")

</div>

Thanks Jeff for the responsiveness 🙂

I tried adding a smart field `id` by joining `memberId` and `proposalId` but it failed, maybe because as you said I did not override the route…

Would you mind giving me more context on that?

Thanks for taking care of that 🙇‍♂️

---

<div class="post-metadata">

**Author:** ![anon39848301](https://avatars.discourse-cdn.com/v4/letter/a/b9e5f3/32.png) [@anon39848301](https://community.forestadmin.com/u/anon39848301)\
**Post date:** [August 18, 2021, 10:13am UTC](https://community.forestadmin.com/t/problem-with-composite-keys-expected-id-to-be-a-string-or-number-received-null/3123/4 "2021-08-18T10:13:49Z")

</div>

(Fun fact - I also tried to add an `id` smart field on my setup, hoping that the serialization process would consider adding it as a JSONAPI serialized `id` - which does not work because smart fields cannot be used as a primary key 🙂 ).

In fact, I think I completely missed the issue here. It is a regression on our end, introduced in 7.7.0. I’ll update the previous ticket to add all the informations I discovered while searching.

Again, sorry for the inconvenience.

---

<div class="post-metadata">

**Author:** ![anon39848301](https://avatars.discourse-cdn.com/v4/letter/a/b9e5f3/32.png) [@anon39848301](https://community.forestadmin.com/u/anon39848301)\
**Post date:** [August 18, 2021, 3:09pm UTC](https://community.forestadmin.com/t/problem-with-composite-keys-expected-id-to-be-a-string-or-number-received-null/3123/5 "2021-08-18T15:09:33Z")

</div>

@Paul_Vidal,

We’ve just released a new version of `forest-express-sequelize@8.0.10` that should fix your issue (You should be able to display proposal members as a related data).

Let me know if you are still having the issue or if it is fixed 🙏

---

<div class="post-metadata">

**Author:** ![Paul\_Vidal](https://dub1.discourse-cdn.com/flex013/user_avatar/community.forestadmin.com/paul_vidal/32/2897_2.png) [@Paul\_Vidal](https://community.forestadmin.com/u/Paul_Vidal)\
**Post date:** [August 19, 2021, 3:54pm UTC](https://community.forestadmin.com/t/problem-with-composite-keys-expected-id-to-be-a-string-or-number-received-null/3123/6 "2021-08-19T15:54:49Z")

</div>

problem solved indeed ❤ Thank you for the awesome support
