amplify-js
amplify-js copied to clipboard
TypeError: "Cannot convert null value to object" - AppSync Filters Not Matching Typescript Filters on SecondaryIndex
Before opening, please confirm:
- [X] I have searched for duplicate or closed issues and discussions.
- [X] I have read the guide for submitting bug reports.
- [X] I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
JavaScript Framework
React Native
Amplify APIs
GraphQL API
Amplify Version
v6
Amplify Categories
api
Backend
Amplify Gen 2 (Preview)
Environment information
System:
OS: macOS 14.4.1
CPU: (10) arm64 Apple M2 Pro
Memory: 1.08 GB / 16.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 20.7.0 - /opt/homebrew/bin/node
Yarn: 1.22.22 - /opt/homebrew/bin/yarn
npm: 10.1.0 - /opt/homebrew/bin/npm
Watchman: 2023.09.04.00 - /opt/homebrew/bin/watchman
Browsers:
Safari: 17.4.1
npmPackages:
%name%: 0.1.0
@aws-amplify/backend: ^1.0.1 => 1.0.2
@aws-amplify/backend-cli: ^1.0.2 => 1.0.3
@aws-amplify/react-native: ^1.1.0 => 1.1.1
@aws-amplify/ui-react-native: ^2.2.0 => 2.2.1
@aws-appsync/utils: ^1.7.0 => 1.7.0
@babel/core: ^7.20.0 => 7.24.5
@babel/plugin-proposal-export-namespace-from: ^7.18.9 => 7.18.9
@babel/plugin-proposal-optional-chaining: ^7.0.0 => 7.21.0
@babel/plugin-transform-arrow-functions: ^7.0.0 => 7.24.1
@babel/plugin-transform-nullish-coalescing-operator: ^7.0.0 => 7.24.1
@babel/plugin-transform-shorthand-properties: ^7.0.0 => 7.24.1
@babel/plugin-transform-template-literals: ^7.0.0 => 7.24.1
@babel/preset-env: ^7.20.0 => 7.24.5
@babel/runtime: ^7.20.0 => 7.24.5
@config-plugins/ffmpeg-kit-react-native: ^8.0.0 => 8.0.0
@expo-google-fonts/m-plus-1p: ^0.2.3 => 0.2.3
@expo-google-fonts/montserrat: ^0.2.3 => 0.2.3
@expo/config-plugins: ~8.0.0 => 8.0.4 (7.9.2)
@expo/metro-runtime: ~3.2.1 => 3.2.1
@gorhom/bottom-sheet: ^4.6.1 => 4.6.1
@react-native-async-storage/async-storage: ^1.23.1 => 1.23.1
@react-native-community/netinfo: 11.3.1 => 11.3.1
@react-navigation/bottom-tabs: ^6.5.20 => 6.5.20
@react-navigation/native: ^6.0.2 => 6.1.17
@react-navigation/native-stack: ^6.0.2 => 6.9.26
@sentry/react-native: ~5.22.0 => 5.22.2
@shopify/flash-list: 1.6.4 => 1.6.4
@types/i18n-js: 3.8.2 => 3.8.2
@types/jest: ^29.2.1 => 29.5.12
@types/lodash.filter: ^4.6.9 => 4.6.9
@types/react: ~18.2.14 => 18.2.79 (18.3.2)
@types/react-test-renderer: ^18.0.0 => 18.3.0
@typescript-eslint/eslint-plugin: ^5.59.0 => 5.62.0
@typescript-eslint/parser: ^5.59.0 => 5.62.0
ContextAPIMixpanel: 0.0.1
HelloWorld: 0.0.1
MixpanelDemo: 0.0.1
SimpleMixpanel: 0.0.1
apisauce: 3.0.1 => 3.0.1
aws-amplify: ^6.3.1 => 6.3.2
aws-amplify/adapter-core: undefined ()
aws-amplify/analytics: undefined ()
aws-amplify/analytics/kinesis: undefined ()
aws-amplify/analytics/kinesis-firehose: undefined ()
aws-amplify/analytics/personalize: undefined ()
aws-amplify/analytics/pinpoint: undefined ()
aws-amplify/api: undefined ()
aws-amplify/api/server: undefined ()
aws-amplify/auth: undefined ()
aws-amplify/auth/cognito: undefined ()
aws-amplify/auth/cognito/server: undefined ()
aws-amplify/auth/enable-oauth-listener: undefined ()
aws-amplify/auth/server: undefined ()
aws-amplify/data: undefined ()
aws-amplify/data/server: undefined ()
aws-amplify/datastore: undefined ()
aws-amplify/in-app-messaging: undefined ()
aws-amplify/in-app-messaging/pinpoint: undefined ()
aws-amplify/push-notifications: undefined ()
aws-amplify/push-notifications/pinpoint: undefined ()
aws-amplify/storage: undefined ()
aws-amplify/storage/s3: undefined ()
aws-amplify/storage/s3/server: undefined ()
aws-amplify/storage/server: undefined ()
aws-amplify/utils: undefined ()
aws-cdk: ^2.141.0 => 2.142.0
aws-cdk-lib: ^2.141.0 => 2.142.0
babel-jest: ^29.2.1 => 29.7.0
cheerio: ^1.0.0-rc.12 => 1.0.0-rc.12
constructs: ^10.3.0 => 10.3.0
date-fns: ^2.30.0 => 2.30.0
esbuild: ^0.21.1 => 0.21.3 (0.20.2)
eslint: 8.17.0 => 8.17.0
eslint-config-prettier: 8.5.0 => 8.5.0
eslint-config-standard: 17.0.0 => 17.0.0
eslint-plugin-import: 2.26.0 => 2.26.0
eslint-plugin-n: ^15.0.0 => 15.7.0
eslint-plugin-promise: 6.0.0 => 6.0.0
eslint-plugin-react: 7.30.0 => 7.30.0
eslint-plugin-react-native: 4.0.0 => 4.0.0
eslint-plugin-reactotron: ^0.1.2 => 0.1.4
ex: ^0.1.4 => 0.1.4
expo: ~51.0.6 => 51.0.7
expo-application: ~5.9.1 => 5.9.1
expo-av: ~14.0.4 => 14.0.4
expo-blur: ~13.0.2 => 13.0.2
expo-build-properties: ^0.12.1 => 0.12.1
expo-clipboard: ~6.0.3 => 6.0.3
expo-constants: ^16.0.1 => 16.0.1
expo-contacts: ~13.0.3 => 13.0.3
expo-dev-client: ~4.0.13 => 4.0.13
expo-device: ~6.0.2 => 6.0.2
expo-font: ~12.0.4 => 12.0.5
expo-haptics: ~13.0.1 => 13.0.1
expo-image-picker: ~15.0.4 => 15.0.4
expo-linear-gradient: ~13.0.2 => 13.0.2
expo-linking: ~6.3.1 => 6.3.1
expo-localization: ~15.0.3 => 15.0.3
expo-modules-autolinking: ^1.11.1 => 1.11.1
expo-notifications: ^0.28.1 => 0.28.1
expo-secure-store: ~13.0.1 => 13.0.1
expo-share-intent: ^2.0.0 => 2.0.0
expo-splash-screen: ^0.27.4 => 0.27.4
expo-status-bar: ~1.12.1 => 1.12.1
expo-store-review: ~7.0.2 => 7.0.2
expo-updates: ~0.25.12 => 0.25.13
expo-video-thumbnails: ~8.0.0 => 8.0.0
ffmpeg-kit-react-native: ^6.0.2 => 6.0.2
i18n-js: 3.9.2 => 3.9.2
jest: ^29.2.1 => 29.7.0
jest-expo: ~51.0.1 => 51.0.1
libphonenumber-js: ^1.11.1 => 1.11.1 (1.9.47)
libphonenumber-js-core: undefined (1.0.0)
libphonenumber-js-max: undefined (1.0.0)
libphonenumber-js-min: undefined (1.0.0)
libphonenumber-js-mobile: undefined (1.0.0)
libphonenumber-js/build: undefined ()
libphonenumber-js/core: undefined ()
libphonenumber-js/max: undefined ()
libphonenumber-js/max/metadata: undefined ()
libphonenumber-js/min: undefined ()
libphonenumber-js/min/metadata: undefined ()
libphonenumber-js/mobile: undefined ()
libphonenumber-js/mobile/examples: undefined ()
libphonenumber-js/mobile/metadata: undefined ()
lodash: ^4.17.21 => 4.17.21
lodash.filter: ^4.6.0 => 4.6.0
lottie-react-native: 6.7.0 => 6.7.0
mixpanel-react-native: ^3.0.2 => 3.0.5
mixpanelexpo: 1.0.0
mobx: 6.10.2 => 6.10.2
mobx-react-lite: 4.0.5 => 4.0.5
mobx-state-tree: 5.3.0 => 5.3.0
patch-package: 6.4.7 => 6.4.7
postinstall-prepare: 1.0.1 => 1.0.1
prettier: 2.8.8 => 2.8.8 (2.3.2, 1.19.1)
react: 18.2.0 => 18.2.0
react-dom: 18.2.0 => 18.2.0
react-native: 0.74.1 => 0.74.1
react-native-blurhash: ^2.0.2 => 2.0.2
react-native-compressor: ^1.8.24 => 1.8.24
react-native-context-menu-view: ^1.16.0 => 1.16.0
react-native-device-info: ^10.13.2 => 10.14.0
react-native-fs: ^2.20.0 => 2.20.0
react-native-gesture-handler: ~2.16.1 => 2.16.2
react-native-get-random-values: ^1.11.0 => 1.11.0
react-native-mime-types: ^2.5.0 => 2.5.0
react-native-mmkv: ^2.12.2 => 2.12.2
react-native-reanimated: ~3.10.1 => 3.10.1
react-native-safe-area-context: ^4.10.1 => 4.10.1
react-native-screens: 3.31.1 => 3.31.1
react-native-static-safe-area-insets: ^2.2.0 => 2.2.0
react-native-touchable-scale: ^2.2.0 => 2.2.0
react-native-url-polyfill: ^2.0.0 => 2.0.0
react-native-vision-camera: ^4.0.3 => 4.0.4
react-native-volume-manager: ^1.10.0 => 1.10.0
react-native-web: ~0.19.6 => 0.19.11
react-native-webview: 13.8.6 => 13.8.6
react-native-youtube-iframe: ^2.3.0 => 2.3.0
react-test-renderer: 18.2.0 => 18.2.0
reactotron-core-client: ^2.8.13 => 2.9.3
reactotron-mst: ^3.1.7 => 3.1.9
reactotron-react-js: ^3.3.11 => 3.3.14
reactotron-react-native: ^5.0.5 => 5.1.7
ts-jest: ^29.1.1 => 29.1.2
ts-node: ^10.9.2 => 10.9.2
tsx: ^4.9.4 => 4.10.2
typescript: ~5.3.3 => 5.3.3 (4.4.4, 4.9.5)
uuid: ^9.0.1 => 9.0.1 (8.3.2, 3.3.2, 7.0.3)
npmGlobalPackages:
@aws-amplify/cli-internal: 12.12.0
@aws-amplify/cli: 12.11.0
@react-native-community/netinfo: 9.4.1
eas-cli: 9.0.6
expo-cli: 6.3.10
firebase-tools: 11.24.1
n: 9.1.0
node-gyp: 10.0.1
node: 20.6.0
npm: 10.7.0
pod-install: 0.2.0
react-native-spinkit: 1.5.1
typescript: 5.4.5
yarn: 1.22.22
Describe the bug
I have a secondaryIndex query set up in AWS Amplify Gen 2. The query throws the error above when the sortKey is set like so:
//MODEL
Post: a
.model({
id: a.id().required(),
reactionTimestamp: a.datetime(),
reactionViewedTimestamp: a.datetime(),
receiverId: a.id().required(),
receiver: a.belongsTo("User", "receiverId"),
senderId: a.id().required(),
sender: a.belongsTo("User", "senderId"),
searchTag: a.string(),
})
.authorization((allow) => [allow.publicApiKey()])
.secondaryIndexes((index) => [
index("receiverId")
.name("unreadPostsReceived")
.sortKeys(["reactionTimestamp"])
.queryField("listPostsByReceiverId"),
]),
//QUERY
const currentUser = await getCurrentUser()
const response = await client.models.Post.listPostsByReceiverId(
{
receiverId: currentUser.userId,
reactionTimestamp: { attributeExists: false }, //throws `TypeError: Cannot convert value of null to object`
}
)
// FIX
const response = await client.models.Post.listPostsByReceiverId(
{
receiverId: currentUser.userId,
reactionTimestamp: { eq: undefined }, // does not throw error
}
)
Expected behavior
Should not throw this error
Reproduction steps
See code above
Code Snippet
// Put your code below this line.
Log output
// Put your logs below this line
aws-exports.js
No response
Manual configuration
No response
Additional configuration
No response
Mobile Device
iPhone 12 Physical
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
Expo 51, React Native 0.74.
Hi @ChristopherGabba, thank you for raising this issue. I was able to consistently reproduce this issue on the latest version of aws-amplify. However, this seems to be expected behavior.
It seems that attributeExists is not an operator on reactionTimestamp, but eq is. This might explain why the former errors out and the latter doesn't.
Trying to use attributeExists also fails on the AppSync console.
@chrisbonifacio great, glad you were able to identify this. I don't think this issue should be closed yet though.
I believe Typescripts intellisense still recommends attributeExists within VScode so that option shouldn't be recommended if it isn't an AppSync compatible filter.
AppSync recommends these:
And Typescript recommends these:
So there is clearly a disconnect. Typescript shouldn't be showing me these options if they aren't possible.
Personally, I really like all the options Typescript suggests and wish AppSync wouldn't limit sortKeys to just those 7. Why would the sortKey allow eq (equals) but not ne (not equals). I hope you guys can expand the sortKey filters to include all those Typescript suggests.
Additionally, I would REALLY like this error to not be "TypeError: Cannot convert null value to object" and it should be "Incompatible Filter Applied - AttributeExistFilter is not supported" or something more reasonible. This error took me a few hours to debug. Honestly even the error in your AppSync screenshot is way better lol...
@ChristopherGabba thank you for pointing this out, totally went over my head when I was reproducing! That would certainly make this a bug
Just double checked and see there is a discrepancy between the schema generated by the transformer:
The transformed type uses ModelStringKeyCondition for reactionTimeStamp
which is correct
but the intellisense is still showing more options than it should
Seems to be confusing it with ModelStringInput
Awesome, yeah this probably explains why I keep getting all these TypeErrors with the new GraphQL format... lol
This isn't only an issue for React Native. Just to bump this, I also see this with Next.js/React.
Apologies for the delayed response. This was fixed a few versions ago in the @aws-amplify/data-schema package.
Please run: npm update @aws-amplify/data-schema to update your project.