DataStore sync fail on startup when model has custom primary key
See original GitHub issueBefore opening, please confirm:
- I have searched for duplicate or closed issues and discussions.
- I have read the guide for submitting bug reports.
- I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
JavaScript Framework
Angular
Amplify APIs
GraphQL API, DataStore
Amplify Categories
api
Environment information
# Put output below this line
System:
OS: Windows 10 10.0.19044
CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
Memory: 2.76 GB / 15.92 GB
Binaries:
Node: 16.16.0 - C:\Program Files\nodejs\node.EXE
npm: 8.18.0 - C:\Program Files\nodejs\npm.CMD
Browsers:
Chrome: 105.0.5195.127
Edge: Spartan (44.19041.1266.0), Chromium (105.0.1343.53)
Internet Explorer: 11.0.19041.1566
npmPackages:
@angular-devkit/build-angular: ~13.0.1 => 13.0.2
@angular/animations: ~13.0.0 => 13.0.1
@angular/animations/browser: undefined ()
@angular/animations/browser/testing: undefined ()
@angular/cdk: ^13.0.1 => 13.0.1
@angular/cdk/a11y: undefined ()
@angular/cdk/accordion: undefined ()
@angular/cdk/bidi: undefined ()
@angular/cdk/clipboard: undefined ()
@angular/cdk/coercion: undefined ()
@angular/cdk/collections: undefined ()
@angular/cdk/drag-drop: undefined ()
@angular/cdk/keycodes: undefined ()
@angular/cdk/layout: undefined ()
@angular/cdk/observers: undefined ()
@angular/cdk/overlay: undefined ()
@angular/cdk/platform: undefined ()
@angular/cdk/portal: undefined ()
@angular/cdk/scrolling: undefined ()
@angular/cdk/stepper: undefined ()
@angular/cdk/table: undefined ()
@angular/cdk/testing: undefined ()
@angular/cdk/testing/protractor: undefined ()
@angular/cdk/testing/selenium-webdriver: undefined ()
@angular/cdk/testing/testbed: undefined ()
@angular/cdk/text-field: undefined ()
@angular/cdk/tree: undefined ()
@angular/cli: ~13.0.1 => 13.0.2
@angular/common: ~13.0.0 => 13.0.1
@angular/common/http: undefined ()
@angular/common/http/testing: undefined ()
@angular/common/testing: undefined ()
@angular/common/upgrade: undefined ()
@angular/compiler: ~13.0.0 => 13.0.1
@angular/compiler-cli: ~13.0.0 => 13.0.1
@angular/compiler/testing: undefined ()
@angular/core: ~13.0.0 => 13.0.1
@angular/core/testing: undefined ()
@angular/forms: ~13.0.0 => 13.0.1
@angular/localize: ^13.0.1 => 13.0.1
@angular/localize/init: undefined ()
@angular/material: ^13.0.1 => 13.0.1
@angular/material/autocomplete: undefined ()
@angular/material/autocomplete/testing: undefined ()
@angular/material/badge: undefined ()
@angular/material/badge/testing: undefined ()
@angular/material/bottom-sheet: undefined ()
@angular/material/bottom-sheet/testing: undefined ()
@angular/material/button: undefined ()
@angular/material/button-toggle: undefined ()
@angular/material/button-toggle/testing: undefined ()
@angular/material/button/testing: undefined ()
@angular/material/card: undefined ()
@angular/material/card/testing: undefined ()
@angular/material/checkbox: undefined ()
@angular/material/checkbox/testing: undefined ()
@angular/material/chips: undefined ()
@angular/material/chips/testing: undefined ()
@angular/material/core: undefined ()
@angular/material/core/testing: undefined ()
@angular/material/datepicker: undefined ()
@angular/material/datepicker/testing: undefined ()
@angular/material/dialog: undefined ()
@angular/material/dialog/testing: undefined ()
@angular/material/divider: undefined ()
@angular/material/divider/testing: undefined ()
@angular/material/expansion: undefined ()
@angular/material/expansion/testing: undefined ()
@angular/material/form-field: undefined ()
@angular/material/form-field/testing: undefined ()
@angular/material/form-field/testing/control: undefined ()
@angular/material/grid-list: undefined ()
@angular/material/grid-list/testing: undefined ()
@angular/material/icon: undefined ()
@angular/material/icon/testing: undefined ()
@angular/material/input: undefined ()
@angular/material/input/testing: undefined ()
@angular/material/list: undefined ()
@angular/material/list/testing: undefined ()
@angular/material/menu: undefined ()
@angular/material/menu/testing: undefined ()
@angular/material/paginator: undefined ()
@angular/material/paginator/testing: undefined ()
@angular/material/progress-bar: undefined ()
@angular/material/progress-bar/testing: undefined ()
@angular/material/progress-spinner: undefined ()
@angular/material/progress-spinner/testing: undefined ()
@angular/material/radio: undefined ()
@angular/material/radio/testing: undefined ()
@angular/material/select: undefined ()
@angular/material/select/testing: undefined ()
@angular/material/sidenav: undefined ()
@angular/material/sidenav/testing: undefined ()
@angular/material/slide-toggle: undefined ()
@angular/material/slide-toggle/testing: undefined ()
@angular/material/slider: undefined ()
@angular/material/slider/testing: undefined ()
@angular/material/snack-bar: undefined ()
@angular/material/snack-bar/testing: undefined ()
@angular/material/sort: undefined ()
@angular/material/sort/testing: undefined ()
@angular/material/stepper: undefined ()
@angular/material/stepper/testing: undefined ()
@angular/material/table: undefined ()
@angular/material/table/testing: undefined ()
@angular/material/tabs: undefined ()
@angular/material/tabs/testing: undefined ()
@angular/material/toolbar: undefined ()
@angular/material/toolbar/testing: undefined ()
@angular/material/tooltip: undefined ()
@angular/material/tooltip/testing: undefined ()
@angular/material/tree: undefined ()
@angular/material/tree/testing: undefined ()
@angular/platform-browser: ~13.0.0 => 13.0.1
@angular/platform-browser-dynamic: ~13.0.0 => 13.0.1
@angular/platform-browser-dynamic/testing: undefined ()
@angular/platform-browser/animations: undefined ()
@angular/platform-browser/testing: undefined ()
@angular/platform-server: ~13.0.0 => 13.0.1
@angular/platform-server/init: undefined ()
@angular/platform-server/testing: undefined ()
@angular/router: ~13.0.0 => 13.0.1
@angular/router/testing: undefined ()
@angular/router/upgrade: undefined ()
@nguniversal/builders: ^13.0.1 => 13.0.1
@nguniversal/express-engine: ^13.0.1 => 13.0.1
@nguniversal/express-engine/tokens: undefined ()
@types/express: ^4.17.0 => 4.17.13
@types/jasmine: ~3.10.0 => 3.10.2
@types/node: ^12.11.1 => 12.20.37
aws-amplify: ^4.3.36 => 4.3.36
express: ^4.15.2 => 4.17.1
ini: ^1.3.5 => 1.3.8 (2.0.0)
inquirer: ^6.5.1 => 6.5.2 (8.2.0)
jasmine-core: ~3.10.0 => 3.10.1
karma: ~6.3.0 => 6.3.9
karma-chrome-launcher: ~3.1.0 => 3.1.0
karma-coverage: ~2.0.3 => 2.0.3
karma-coverage-coffee-example: 1.0.0
karma-jasmine: ~4.0.0 => 4.0.1
karma-jasmine-html-reporter: ~1.7.0 => 1.7.0
rxjs: ~7.4.0 => 7.4.0 (6.6.7, 7.5.6, 5.5.12)
rxjs/ajax: undefined ()
rxjs/fetch: undefined ()
rxjs/internal-compatibility: undefined ()
rxjs/operators: undefined ()
rxjs/testing: undefined ()
rxjs/webSocket: undefined ()
tslib: ^2.3.0 => 2.3.1 (1.14.1, 2.1.0)
typescript: ~4.4.3 => 4.4.4
ulid: ^2.3.0 => 2.3.0
zone-mix: undefined ()
zone-node: undefined ()
zone-testing: undefined ()
zone.js: ~0.11.4 => 0.11.4
zone.js/async-test: undefined ()
zone.js/async-test.min: undefined ()
zone.js/fake-async-test: undefined ()
zone.js/fake-async-test.min: undefined ()
zone.js/jasmine-patch: undefined ()
zone.js/jasmine-patch.min: undefined ()
zone.js/long-stack-trace-zone: undefined ()
zone.js/long-stack-trace-zone.min: undefined ()
zone.js/mocha-patch: undefined ()
zone.js/mocha-patch.min: undefined ()
zone.js/proxy: undefined ()
zone.js/proxy.min: undefined ()
zone.js/sync-test: undefined ()
zone.js/sync-test.min: undefined ()
zone.js/task-tracking: undefined ()
zone.js/task-tracking.min: undefined ()
zone.js/webapis-media-query: undefined ()
zone.js/webapis-media-query.min: undefined ()
zone.js/webapis-notification: undefined ()
zone.js/webapis-notification.min: undefined ()
zone.js/webapis-rtc-peer-connection: undefined ()
zone.js/webapis-rtc-peer-connection.min: undefined ()
zone.js/webapis-shadydom: undefined ()
zone.js/webapis-shadydom.min: undefined ()
zone.js/wtf: undefined ()
zone.js/wtf.min: undefined ()
zone.js/zone-bluebird: undefined ()
zone.js/zone-bluebird.min: undefined ()
zone.js/zone-error: undefined ()
zone.js/zone-error.min: undefined ()
zone.js/zone-legacy: undefined ()
zone.js/zone-legacy.min: undefined ()
zone.js/zone-patch-canvas: undefined ()
zone.js/zone-patch-canvas.min: undefined ()
zone.js/zone-patch-cordova: undefined ()
zone.js/zone-patch-cordova.min: undefined ()
zone.js/zone-patch-electron: undefined ()
zone.js/zone-patch-electron.min: undefined ()
zone.js/zone-patch-fetch: undefined ()
zone.js/zone-patch-fetch.min: undefined ()
zone.js/zone-patch-jsonp: undefined ()
zone.js/zone-patch-jsonp.min: undefined ()
zone.js/zone-patch-message-port: undefined ()
zone.js/zone-patch-message-port.min: undefined ()
zone.js/zone-patch-promise-test: undefined ()
zone.js/zone-patch-promise-test.min: undefined ()
zone.js/zone-patch-resize-observer: undefined ()
zone.js/zone-patch-resize-observer.min: undefined ()
zone.js/zone-patch-rxjs: undefined ()
zone.js/zone-patch-rxjs-fake-async: undefined ()
zone.js/zone-patch-rxjs-fake-async.min: undefined ()
zone.js/zone-patch-rxjs.min: undefined ()
zone.js/zone-patch-socket-io: undefined ()
zone.js/zone-patch-socket-io.min: undefined ()
zone.js/zone-patch-user-media: undefined ()
zone.js/zone-patch-user-media.min: undefined ()
npmGlobalPackages:
@angular-devkit/schematics-cli: 0.801.1
@angular/cli: 14.1.3
@aws-amplify/cli: 10.0.0
@ionic/cli: 6.6.0
angular: 1.7.8
ng2-custom-carousel: 0.0.30
npm: 8.18.0
Describe the bug
System fails to sync on startup when creating a model providing a custom primary key composed by partition key and sort key. From this point none of the sync subscriptions works and updates DataStore. It looks like, on startup, system tries to initialize the subscriptions using the default βidβ field as primary key but the model is using as primary key a composite key composed by the fields βpkβ and βskβ, as specified in the schema. It is weird because I can still see socket messages from the server of a new instance created in the backend but DataStore is not actualized with this new instances. The Api subscriptions also work and react to onCreate events.
Expected behavior
Model sync and reacting to new instances created on the backend.
Reproduction steps
PS C:> amplify add api
? Select from one of the below mentioned services: GraphQL
? Here is the GraphQL API that we will create. Select a setting to edit or continue Name: ********
? Provide API name: ************
? Here is the GraphQL API that we will create. Select a setting to edit or continue Authorization modes: API key (default, expiration time: 7 days from now)
? Choose the default authorization type for the API Amazon Cognito User Pool
Use a Cognito user pool configured as a part of this project.
? Configure additional auth types? No
? Here is the GraphQL API that we will create. Select a setting to edit or continue Conflict detection (required for DataStore): Disabled
? Enable conflict detection? Yes
? Select the default resolution strategy Auto Merge
? Here is the GraphQL API that we will create. Select a setting to edit or continue Continue
? Choose a schema template: Single object with fields (e.g., βTodoβ with ID, name, description)
Learn more about β@authβ authorization rules here: https://docs.amplify.aws/cli/graphql/authorization-rules β GraphQL schema compiled successfully.
Edit your schema at β¦\amplify\backend\api*\schema.graphql or place .graphql files in a directory at β¦\amplify\backend\api*\schema β Do you want to edit the schema now? (Y/n) Β· no β Successfully added resource ******** locally
β Some next steps: βamplify pushβ will build all your local backend resources and provision it in the cloud βamplify publishβ will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
PS C:> amplify push
/ Fetching updates to backend environment: dev from the cloud.β
GraphQL schema compiled successfully.
Edit your schema at β¦\amplify\backend\api**\schema.graphql or place .graphql files in a directory at β¦\amplify\backend\api*\schema β Successfully pulled backend environment dev from the cloud. \ Building resource api/********β GraphQL schema compiled successfully.
Edit your schema at β¦\amplify\backend\api*\schema.graphql or place .graphql files in a directory at β¦\amplify\backend\api*\schema
Current Environment: dev
ββββββββββββ¬βββββββββββββββββββ¬ββββββββββββ¬ββββββββββββββββββββ β Category β Resource name β Operation β Provider plugin β ββββββββββββΌβββββββββββββββββββΌββββββββββββΌββββββββββββββββββββ€ β Api β *********β Create β awscloudformation β ββββββββββββΌβββββββββββββββββββΌββββββββββββΌββββββββββββββββββββ€ β Auth β *************** β No Change β awscloudformation β ββββββββββββΌβββββββββββββββββββΌββββββββββββΌββββββββββββββββββββ€ β Storage β ****************β No Change β awscloudformation β ββββββββββββΌβββββββββββββββββββΌββββββββββββΌββββββββββββββββββββ€ β Hosting β amplifyhosting β No Change β β ββββββββββββ΄βββββββββββββββββββ΄ββββββββββββ΄ββββββββββββββββββββ ? Are you sure you want to continue? Yes β GraphQL schema compiled successfully.
Edit your schema at β¦\amplify\backend\api*\schema.graphql or place .graphql files in a directory at β¦\amplify\backend\api**\schema
- Building resource api/********β GraphQL schema compiled successfully.
Edit your schema at β¦\amplify\backend\api****\schema.graphql or place .graphql files in a directory at β¦\amplify\backend\api*\schema ? Do you want to generate code for your newly created GraphQL API Yes ? Choose the code generation language target angular ? Enter the file name pattern of graphql queries, mutations and subscriptions src\graphql***.graphql ? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions Yes ? Enter maximum statement depth [increase from default if your schema is deeply nested] 2 ? Enter the file name for the generated code src\app\API.service.ts
Deploying resources into dev environment. This will take a few minutes. β Ή
Deployment completed.
Deploying root stack [ ================================-------- ] 4/5
amplify--dev-65545 AWS::CloudFormation::Stack UPDATE_COMPLETE Wed Sep 28 2022 20:32:24β¦
storagel*************** AWS::CloudFormation::Stack UPDATE_COMPLETE Wed Sep 28 2022 20:27:41β¦
auth*************** AWS::CloudFormation::Stack UPDATE_COMPLETE Wed Sep 28 2022 20:27:41β¦
api*********** AWS::CloudFormation::Stack CREATE_COMPLETE Wed Sep 28 2022 20:32:20β¦
Deployed api [ ======================================== ] 9/9
GraphQLAPI AWS::AppSync::GraphQLApi CREATE_COMPLETE Wed Sep 28 2022 20:27:54β¦
GraphQLAPI************ AWS::AppSync::DataSource CREATE_COMPLETE Wed Sep 28 2022 20:27:58β¦
AmplifyDataStore*****************β¦ AWS::IAM::Role CREATE_COMPLETE Wed Sep 28 2022 20:28:19β¦
DataStore AWS::DynamoDB::Table CREATE_COMPLETE Wed Sep 28 2022 20:28:14β¦
GraphQLAPITransformerSchema3Cβ¦ AWS::AppSync::GraphQLSchema CREATE_COMPLETE Wed Sep 28 2022 20:28:59β¦
DynamoDBAccess************ AWS::IAM::Policy CREATE_COMPLETE Wed Sep 28 2022 20:31:21β¦
Edit your schema at β¦\amplify\backend\api*\schema.graphql or place .graphql files in a directory at β¦\amplify\backend\api*\schema Successfully generated models. Generated models can be found in β¦\src β Code generated successfully and saved in file src\app\API.service.ts β Successfully generated models in the cloud.
GraphQL endpoint: https://************************************************************.amazonaws.com/graphql
GraphQL transformer version: 2
PS C:>
Code Snippet
// Put your code below this line.
import { Component, OnInit, OnDestroy } from '@angular/core';
import { DataStore } from 'aws-amplify';
import { Subscription } from 'rxjs';
import { Item } from 'src/models';
@Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.sass']
})
export class UserComponent implements OnInit, OnDestroy {
private newItemSubscription: Subscription | null = null;
constructor() { }
ngOnInit(): void {
this.newItemSubscription = <Subscription>(
DataStore.observeQuery(Item).subscribe((msg: any) => {
console.log('msg Item:', msg);
})
);
}
ngOnDestroy(): void {
if (this.newItemSubscription) {
this.newItemSubscription.unsubscribe();
}
this.newItemSubscription = null;
}
}
Log output
// Put your logs below this line
[WARN] 54:58.801 DataStore - subscriptionError Connection failed: {"errors":[{"message":"Validation error of type FieldUndefined: Field 'id' in type 'Item' is undefined @ 'onCreateItem/id'"}]}
[WARN] 54:58.803 DataStore
{
"recoverySuggestion": "Ensure app code is up to date, auth directives exist and are correct on each model, and that server-side data has not been invalidated by a schema change. If the problem persists, search for or create an issue: https://github.com/aws-amplify/amplify-js/issues",
"localModel": null,
"message": "Connection failed: {\"errors\":[{\"message\":\"Validation error of type FieldUndefined: Field 'id' in type 'Item' is undefined @ 'onCreateItem/id'\"}]}",
"model": "Item",
"operation": "Create",
"errorType": "Unknown",
"process": "subscribe",
"remoteModel": null,
"cause": {
"provider": {
"_config": {
"aws_project_region": "eu-central-1",
"aws_cognito_identity_pool_id": "**********************************************************",
"aws_cognito_region": "eu-central-1",
"aws_user_pools_id": "*************************",
"aws_user_pools_web_client_id": "*********************************",
"oauth": {},
"aws_cognito_username_attributes": [
"EMAIL"
],
"aws_cognito_social_providers": [],
"aws_cognito_signup_attributes": [
"EMAIL"
],
"aws_cognito_mfa_configuration": "OFF",
"aws_cognito_mfa_types": [
"SMS"
],
"aws_cognito_password_protection_settings": {
"passwordPolicyMinLength": 8,
"passwordPolicyCharacters": []
},
"aws_cognito_verification_mechanisms": [
"EMAIL"
],
"aws_user_files_s3_bucket": "***************************",
"aws_user_files_s3_bucket_region": "eu-central-1",
"aws_appsync_graphqlEndpoint": "https://********************************.appsync-api.eu-central-1.amazonaws.com/graphql",
"aws_appsync_region": "eu-central-1",
"aws_appsync_authenticationType": "AMAZON_COGNITO_USER_POOLS"
},
"socketStatus": 0,
"keepAliveTimeout": 300000,
"subscriptionObserverMap": {},
"promiseArray": [],
"connectionStateMonitor": {
"_linkedConnectionState": {
"networkState": "connected",
"connectionState": "disconnected",
"intendedConnectionState": "disconnected",
"keepAliveState": "healthy"
},
"_linkedConnectionStateObservable": {},
"_linkedConnectionStateObserver": {
"_subscription": {
"_observer": {},
"_state": "ready"
}
}
},
"keepAliveTimeoutId": 129,
"keepAliveAlertTimeoutId": 130
},
"error": {
"errors": [
{
"message": "Connection failed: {\"errors\":[{\"message\":\"Validation error of type FieldUndefined: Field 'id' in type 'Item' is undefined @ 'onCreateItem/id'\"}]}"
}
]
}
}
}
ERROR Error: Uncaught (in promise): Object: {"data":null,"errors":[{"path":null,"locations":[{"line":9,"column":7,"sourceName":null}],"message":"Validation error of type FieldUndefined: Field 'id' in type 'Item' is undefined @ 'syncItems/items/id'"}]}
aws-exports.js
No response
Manual configuration
No response
Additional configuration
type Item @model @auth(rules: [{allow: private}]) {
pk: ID! @primaryKey(sortKeyFields: ["sk"])
sk: ID!
}
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
No response
Issue Analytics
- State:
- Created a year ago
- Comments:14 (5 by maintainers)
Custom primary key support is now released in
aws-amplify@4.3.38
/@aws-amplify/datastore@3.13.0
. Let us know if you have an issue after upgrading.pull request changes has been merged and waiting for the release. Will close the ticket once released.