Amplify-js: DataStore: "Models are not topologically sortable. Please verify your schema."

Created on 23 Dec 2019  路  9Comments  路  Source: aws-amplify/amplify-js

Describe the bug
When generating models based on an existing schema with several relationships I get this strange error that I cannot understand:
"Uncaught Error: Models are not topologically sortable. Please verify your schema."

To Reproduce
Use a complex existing schema and generate models.

* Env *
MacOS 10.15.1
Amplify cli 4.7.0
Amplify Core 2.2.1

This is the error, I don't have to use a model or anything, it's happening on init.
Screenshot 2019-12-23 at 14 43 19

This is the schema, which works fine without Datastore (as far as I know).

type Collection
  @model
  @key(name: "collectionByProfile", fields: ["profileID"])
  @auth(
    rules: [
      { allow: owner }
      {
        allow: groups
        groups: ["admins"]
        queries: [get, list]
        mutations: [create, update, delete]
      }
      { allow: groups, groups: ["members"], queries: [get, list] }
    ]
  ) {
  id: ID!
  name: String!
  description: String!
  profileID: ID!
  cover: Post
  flagged: Boolean
  removed: Boolean
  trust: Int
  profile: Profile @connection(fields: ["profileID"])
  posts: [Post] @connection(keyName: "postsInCollection", fields: ["id"])
}

type S3Object @model {
  s3_bucket_name: String
  s3_object_key: String
}

type Post
  @model
  @key(name: "postsInCollection", fields: ["collectionID", "body"])
  @auth(
    rules: [
      { allow: owner }
      {
        allow: groups
        groups: ["admins"]
        queries: [get, list]
        mutations: [create, update, delete]
      }
      { allow: groups, groups: ["members"], queries: [get, list] }
    ]
  ) {
  id: ID!
  body: String!
  reference: Post @connection(fields: ["id"])
  collectionID: ID!
  collection: Collection @connection(fields: ["collectionID"])
  media: S3Object
  tags: [TagsPosts] @connection(keyName: "byPost", fields: ["id"])
  location: Location @connection(fields: ["id"])
  comments: [Comment] @connection(name: "PostComments")
  flagged: Boolean
  removed: Boolean
  trust: Int
  likes: Int
}

type Like
  @model
  @auth(
    rules: [
      { allow: owner }
      {
        allow: groups
        groups: ["admins"]
        queries: [get, list]
        mutations: [create, update, delete]
      }
    ]
  )
  @key(
    name: "byUser"
    fields: ["createdBy", "createdAt"]
    queryField: "likesByUser"
  ) {
  id: ID!
  postId: ID!
  createdBy: ID!
  createdAt: String!
  liked: Boolean
}

type Comment
  @model
  @auth(
    rules: [
      { allow: owner }
      {
        allow: groups
        groups: ["admins"]
        queries: [get, list]
        mutations: [create, update, delete]
      }
    ]
  ) {
  id: ID!
  content: String
  likes: Int
  post: Post @connection(name: "PostComments")
}

type TagsPosts
  @model(queries: null)
  @auth(
    rules: [
      { allow: owner }
      {
        allow: groups
        groups: ["admins"]
        queries: [get, list]
        mutations: [create, update, delete]
      }
    ]
  )
  @key(name: "byTag", fields: ["tagID", "postID"])
  @key(name: "byPost", fields: ["postID", "tagID"]) {
  id: ID!
  postID: ID!
  tagID: ID!
  post: Post! @connection(fields: ["postID"])
  tag: Tag! @connection(fields: ["tagID"])
}

type Tag
  @model
  @auth(
    rules: [
      {
        allow: groups
        groups: ["admins"]
        queries: [get, list]
        mutations: [create, update]
      }
      {
        allow: groups
        groups: ["members"]
        queries: [get, list]
        mutations: [update]
      }
    ]
  ) {
  id: ID!
  name: String!
  display_name: String!
  posts: [TagsPosts] @connection(keyName: "byTag", fields: ["id"])
}

type Location
  @model
  @auth(
    rules: [
      { allow: owner }
      {
        allow: groups
        groups: ["admins"]
        queries: [get, list]
        mutations: [create, update, delete]
      }
      { allow: groups, groups: ["members"], queries: [get, list] }
    ]
  ) {
  id: ID!
  profileID: ID!
  postID: ID!
  city: String!
  country: String!
}

type Profile
  @model
  @auth(
    rules: [
      { allow: owner }
      {
        allow: groups
        groups: ["admins"]
        queries: [get, list]
        mutations: [create, update, delete]
      }
      { allow: groups, groups: ["members"], queries: [get, list] }
    ]
  ) {
  id: ID!
  name: String!
  description: String
  logged_in: String
  trust: Int
  # tags: [Tag] @connection(keyName: "tagsByProfile", fields: ["id"])
  collections: [Collection]
    @connection(keyName: "collectionByProfile", fields: ["id"])
  location: Location @connection(fields: ["id"])
  following: [Profile]
  blocked: [Profile]
}

DataStore bug

All 9 comments

@raelmiu

I confirmed the issue, the cause is self referencing types, I am working on a fix for this.

With this schema I was able to reproduced the problem

type Post @model {
  id: ID!
  body: String!
  reference: Post @connection(fields: ["id"])
  collectionID: ID!
  flagged: Boolean
  removed: Boolean
  trust: Int
  likes: Int
}

Post has a self reference on reference field.

That's really interesting. Not all that surprising either I guess. Thank you!

@raelmiu the fix for this is already merged in master, you can try on your app by installing @aws-amplify/datastore@unstable

We should publish a new @latest version soon

I'm getting this issue using 1.0.7 and without a referencing type. @elorzafe

I am getting the same issue. Error: Models are not topologically sortable. Please verify your schema..
I added amplify-app to my existing project and ran an npm run amplify-modelgen.
Well, it doesn't particularly say where's the issue with a huge schema as bellow as I started adding datastore offline ability to my app.

The schema looks like,

type Item @model
  @auth(rules: [
    { allow: public, provider: apiKey, operations: [read] },
    { allow: groups, groups: ["admin"] }
  ]) {
  id: ID!
  name: String!
  soldUnits: String!
  soldAs: [Float!]
  price: Float!
  isAvailable: Boolean!
  availableAmount: Float!
  catagory: String!
  isVeg: Boolean!
  offer: [String!]
  about: String
  storage: String
  benifits: String
  otherInfo: String
  rating: Int
  keywords: [String!]
  reviews: [String]
  images: [String]
  updatedBy: String
  addedBy: String
  inventroy: Inventory @connection(name: "ItemInventory")
}

type User @model
  @auth(rules: [
    { allow: owner },
    { allow: groups, groups: ["admin"] }
  ]) {
  id: ID!
  firstName: String!
  lastName: String!
  about: String!
  phoneNumber: Int!
  countryCode: String!
  addresses: [Address] @connection
  orders: [Order] @connection(name: "OwnOrder")
  cart: [CartItem] @connection
}

type CartItem @model
  @auth(rules: [
    { allow: owner },
    { allow: groups, groups: ["admin"] }
  ]) {
    id: ID!
    count: Int!
    item: Item @connection
}

type Address @model {
  lat: Float!
  long: Float!
  fullAddress: String!
  apartment: String!
  street: String
  district: String!
  city: String
  state: String!
  zip: Int!
  country: String!
}

type InventoryAddress @model
  @auth(rules: [
    { allow: owner },
    { allow: groups, groups: ["admin"] }
  ]) {
  id: ID!
  address: Address @connection
  inventroy: Inventory! @connection(name: "InventoryAddress")
}

type Order @model
  @auth(rules: [
    { allow: owner, operations: [create, read] },
    { allow: groups, groups: ["admin"] }
  ]) {
  id: ID!
  orderdate: AWSDate!
  ordertime: AWSTime!
  deliverySlot: String!
  deliveryDate: AWSDate!
  deliveryInput: String!
  deliveryPhoneNumber: Int!
  deliveryPhoneCountryCode: String!
  deliveryAddress: String!
  deliveredTime: AWSDate
  deliveredDate: AWSDate
  deliveryCharges: Float!
  totalAmount: Float!
  paidAmount: Float!
  discount: Float!
  unpaidAmount: Float!
  status: String!
  paymentMethod: String!
  paymentId: String!
  itemsCount: Int!
  deliverAssignedTo: Patron @connection(name: "PatronOrder")
  owner: User @connection(name: "OwnOrder")
  items: [Item] @connection
  inventroyDetails: Inventory @connection(name: "InventoryOrder")
}

type Patron @model
  @auth(rules: [
    { allow: groups, groups: ["admin"] }
  ]) {
  id: ID!
  age: Int!
  firstName: String!
  lastName: String!
  about: String
  workTime: String
  rating: Int!
  reviews: [String]
  addressProof: String!
  role: String
  workArea: Address @connection
  address: Address @connection
  deliveries: [Order] @connection(name: "PatronOrder")
  inventroyDetails: Inventory! @connection(name: "PatronInventory")
  addedItems: [Item] @connection
}

type Inventory @model
  @auth(rules: [
    { allow: public, provider: apiKey, operations: [read] },
    { allow: groups, groups: ["admin"] }
  ]) {
  id: ID!
  address: InventoryAddress @connection(name: "InventoryAddress")
  patron: [Patron] @connection(name: "PatronInventory")
  items: [Item] @connection(name: "ItemInventory")
  orders: [Order] @connection(name: "InventoryOrder")
  manager: Patron @connection
  admins: [Patron] @connection
}

My system info

  System:
    OS: macOS Mojave 10.14.5
    CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
    Memory: 4.03 GB / 16.00 GB
    Shell: 5.3 - /bin/zsh
  Binaries:
    Node: 12.4.0 - ~/.nvm/versions/node/v12.4.0/bin/node
    Yarn: 1.16.0 - ~/.nvm/versions/node/v12.4.0/bin/yarn
    npm: 6.9.0 - ~/.nvm/versions/node/v12.4.0/bin/npm
  Browsers:
    Chrome: 80.0.3987.149
    Firefox: 72.0.1
    Safari: 12.1.1
  npmPackages:
    @aws-amplify/api: ^2.1.6 => 2.1.6 
    @aws-amplify/auth: ^2.1.6 => 2.1.6 
    @aws-amplify/core: ^2.2.5 => 2.2.5 
    @aws-amplify/datastore: ^1.0.8 => 1.0.8 
    @babel/plugin-proposal-optional-chaining: ^7.9.0 => 7.9.0 
    @testing-library/jest-dom: ^4.2.4 => 4.2.4 
    @testing-library/react: ^9.3.2 => 9.5.0 
    @testing-library/user-event: ^7.1.2 => 7.2.1 
    aws-amplify-react: ^3.1.7 => 3.1.7 
    aws-appsync: ^3.0.2 => 3.0.2 
    aws-appsync-react: 2.0.2 => 2.0.2 
    classnames: ^2.2.6 => 2.2.6 
    customize-cra: ^0.9.1 => 0.9.1 
    graphql-tag: ^2.10.3 => 2.10.3 
    ini: ^1.3.5 => 1.3.5 
    inquirer: ^6.5.1 => 6.5.2 
    node-sass: ^4.13.1 => 4.13.1 
    prop-types: ^15.7.2 => 15.7.2 
    react: ^16.13.1 => 16.13.1 
    react-apollo: ^3.1.3 => 3.1.3 
    react-app-rewired: ^2.1.5 => 2.1.5 
    react-dom: ^16.13.1 => 16.13.1 
    react-hook-form: ^5.1.3 => 5.1.3 
    react-router-dom: ^5.1.2 => 5.1.2 
    react-scripts: 3.4.1 => 3.4.1 
    react-select: ^3.0.8 => 3.1.0 
    use-immer: ^0.0.5 => 0.0.5 
  npmGlobalPackages:
    @aws-amplify/cli: 4.16.1
    @babel/cli: 7.5.0
    @babel/core: 7.5.0
    create-react-app: 3.3.0
    firebase-tools: 7.10.0
    jshint: 2.10.2
    lerna: 3.19.0
    ngrok: 2.2.3
    npm: 6.9.0
    pkg: 4.4.1
    rimraf: 3.0.0
    serverless-next.js: 1.9.3
    serverless: 1.66.0
    yarn: 1.16.0

Any help please?

@subhendukundu try this:

  1. comment out all the @connections you have in your schema then deploy
  2. If it works then add them + deploy one at a time

@elorzafe I guess we have to reopen this issue. Having the latest amplify version running I'm facing the problem again: Error: Models are not topologically sortable. Please verify your schema.

@elorzafe fixed it, it was my mistake. Had something missing in my connection schema!

Up ! I am having this issue in my project

Was this page helpful?
0 / 5 - 0 ratings