Error after ejecting to bare workflow. "null is not an object" error evaluating (_expoConstants.default.manifest.releaseChannel)

Please provide the following:

  1. SDK Version: 34.0.0
  2. Platforms(Android/iOS/web/all): Android

I’ve recently ejected my app to the bare workflow and I’m getting this error whenever I build the Android app with react-native run-android(image below): "null is not an object" error evaluating (_expoConstants.default.manifest.releaseChannel)

Curiously, the app runs perfectly if I use expo start instead…

I’ve looked through the forums and I’ve found this very similar error, unfortunately it was automatically closed without any suggestions I could follow

My case is slightly different, I only use expo libraries in one place (below). And I seem to get the error even if I remove the import to expo-constants and use of the Constants.

import Sentry from 'sentry-expo';
import Constants from 'expo-constants';
import store from "../store"
import moment from "moment"

/**
 * This option activates Sentry in development, if we want to test it 
 * we simply uncomment the line below
 */
// Sentry.enableInExpoDevelopment=true

Sentry.config(.....).install();

export const configureTagContext = () => {
    Sentry.setTagsContext({
        appVersion: Constants.platform.android.versionCode,
        deviceInfo: {
            deviceName: Constants.deviceName,
        }
    })

    Sentry.setExtraContext({
        installationId: Constants.installationId,
        isRunningInExpo: Constants.appOwnership
    })
}

package.json

{
  "name": "empty-project-template",
  "private": true,
  "scripts": {
    "start": "react-native start",
    "android": "react-native run-android",
    "release-android": "react-native run-android --variant=release",
    "ios": "react-native run-ios",
    "test": "node ./node_modules/jest/bin/jest.js --watch"
  },
  "jest": {
    "preset": "jest-expo",
    "transform": {
      "\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
    },
    "verbose": true,
    "cacheDirectory": "./cache",
    "coveragePathIgnorePatterns": [],
    "transformIgnorePatterns": [
      "node_modules/(?!((jest-)?react-native|react-clone-referenced-element|expo(nent)?|@expo(nent)?/.*|react-navigation|sentry-expo))"
    ],
    "setupFiles": [
      "<rootDir>/node_modules/react-native/jest/setup.js",
      "<rootDir>/node_modules/jest-expo/src/setup.js"
    ],
    "setupTestFrameworkScriptFile": "<rootDir>/testConfig/setup.js",
    "moduleNameMapper": {
      "\\.(jpg|jpeg|png|svg)$": "<rootDir>/testConfig/imageMock.js",
      "\\.(css|scss)$": "identity-obj-proxy"
    }
  },
  "dependencies": {
    "expo": "^34.0.3",
    "expo-constants": "^6.0.0",
    "firebase": "^5.8.4",
    "jetifier": "^1.6.4",
    "moment": "^2.24.0",
    "react": "16.8.3",
    "react-dom": "16.8.3",
    "react-native": "0.59.10",
    "react-native-country-picker-modal": "^0.7.1",
    "react-native-datepicker": "^1.7.2",
    "react-native-elements": "^0.19.1",
    "react-native-gesture-handler": "^1.3.0",
    "react-native-paper": "^2.16.0",
    "react-native-phone-input": "^0.2.1",
    "react-native-reanimated": "^1.1.0",
    "react-native-screens": "1.0.0-alpha.22",
    "react-native-swipe-gestures": "^1.0.3",
    "react-native-unimodules": "~0.5.2",
    "react-native-web": "^0.11.4",
    "react-navigation": "^3.0.9",
    "react-navigation-material-bottom-tabs": "^1.0.0",
    "react-redux": "^5.1.1",
    "redux": "^4.0.1",
    "redux-persist": "^5.9.1",
    "redux-thunk": "^2.3.0",
    "sentry-expo": "^1.13.0",
    "uuid": "^3.3.2"
  },
  "devDependencies": {
    "enzyme": "^3.9.0",
    "enzyme-adapter-react-16": "^1.9.1",
    "jest": "^23.2.0",
    "jest-enzyme": "^7.0.1",
    "jest-expo": "^34.0.0",
    "jsdom": "^13.2.0",
    "react-dom": "^16.8.2",
    "redux-logger": "^3.0.6"
  }
}

In the conversation in the related post an Expo Team member states

I think since the manifest is either served through expo-cli or created on expo publish , bare apps wouldn’t have access to it. I’ll confirm this, and if it’s the case I’ll modify the docs to reflect this.strong text

But as stated above removing my references to Constants doesn’t appear to solve the problem.
Any help or direction is appreciated as I’m fully lost on this one.

Hi @tony-boresha

Can you change appVersion: Constants.platform.android.versionCode to this and see if it works?

Sentry.setTagsContext({
        appVersion: '1.0',
        deviceInfo: {
            deviceName: Constants.deviceName,
        }
    })

We ended up using just Constants.deviceName from the expo-constant package. Also, there is a new update of the expo-constant package, i think its in version 7.0.0, you should also try to update it and see if the bug its already fixed.

1 Like

Thanks a ton for helping man. I actually just figured out what’s been breaking it (not 5 mins ago), and its a combination of the manifest key being unset in Constants and unsafe code in sentry-expo.

That code is fired when Sentry.config (v1.13.0) or Sentry.init (2.0.0) is called, so it crashes immediately, regardless of what you do with the Constants import.

Line 20 here (sentry-expo/index.js at 7f3f13b55cbcf21b066d82ff33c583591abce2c7 · expo/sentry-expo · GitHub) assumes there is a Constants.manifest object so it goes straight for Constants.manifest.releaseChannel.

const originalSentryConfig = Sentry.config;
Sentry.config = (dsn, options = {}) => {
  let defaultOptions = {
    tags: {
      ...(options.tags || {}),
      deviceId: Constants.deviceId,
      appOwnership: Constants.appOwnership,
      expoVersion: Constants.expoVersion,
      expoSdkVersion: Constants.sdkVersion,
      expoReleaseChannel: Constants.manifest.releaseChannel,
      expoAppVersion: Constants.manifest.version,
      expoAppPublishedTime: Constants.manifest.publishedTime,
    },
  };

But as @charliecruzan said on your post:

the manifest is either served through expo-cli or created on expo publish , bare apps wouldn’t have access to it.

As far as I can tell this means that anyone running a bare RN app will have a showstopping bug if they use sentry-expo. So to follow on your question, it doesn’t look like expo-constants v6.0.0 is compatible with the bare workflow, if you use sentry-expo.

Version 2.0.0 of sentry-expo has the same kind of bug, but a few lines down. Now it fails on line 147 instead: (sentry-expo/index.js at 3707ee15a35175e3779ea0a053a7ae23b3485939 · expo/sentry-expo · GitHub)

 const release = Constants.manifest.revisionId || 'UNVERSIONED';

For now I’ve put in this 4-line workround:

import * as manifest from "../app.json"
if (!Constants.manifest){
    Constants.manifest = manifest.expo
}

npm run android works now.

Unfortunately, the error message above didn’t help. It took me 2 dev-days to solve this.
image

The only clue to all of this is the function name which was called, with no context… if it had at least shown the object that function had fired on this would have taken less hours to solve.

1 Like

Hey @tony-boresha,

Thanks for the detailed investigation here. Would you be able to create a Github Issue with as much relevant information and a reproducible example if possible, so we can track this properly?

Cheers,
Adam

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.