When changing the app descriptor for my ACE app, it throws TypeError: self.register is not a function

Hi all, pretty new to connect app development and node+react in general.

I have a connect app which is just Atlassian connect express plus react, using Typescript for the react parts. Running the app is fine and I can install it in my instance.
However, if I make changes to the app descriptor (atlassian-connect.json) while the server is running , it crashes out with the following error:

Re-registering due to atlassian-connect.json change

TypeError: self.register is not a function
    at FSWatcher.<anonymous> (C:\Users\dominic.cousins\GitHub\cloud-command-centre\node_modules\atlassian-connect-express\lib\index.js:66:30)
    at FSWatcher.emit (events.js:223:5)
    at FSEvent.FSWatcher._handle.onchange (internal/fs/watchers.js:131:12)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

The error seems to be occurring in the js provided by atlassian-connect-express but I can’t believe that is actually the problem. Any help is appreciated and I will provide anything I can as it’s requested. Such files can be found below.

Cheers, Dominic

My package.json:

    "name": "starter-app",
    "version": "1.0.0",
    "private": true,
    "license": "UNLICENSED",
    "scripts": {
        "start": "node app.js",
        "build": "tsc",
        "restart": "yarn build && yarn start"
    "engines": {
        "node": "^12"
    "dependencies": {
        "@types/node": "^12.12.20",
        "atlassian-connect-express": "^4.0.1",
        "body-parser": "^1.19.0",
        "compression": "^1.7.4",
        "cookie-parser": "^1.4.4",
        "dotenv": "^8.2.0",
        "errorhandler": "^1.5.1",
        "express": "^4.17.1",
        "express-hbs": "*",
        "morgan": "^1.9.1",
        "pg": "^7.15.0",
        "sequelize": "^4.42.0",
        "static-expiry": "^0.0.11",
        "typescript": "^3.7.3"

My app.js (which is very similar to the default ACE file):

// Import Environmental Variables

// Startup Text
const os = require('os');
console.log("|                                                                                   |");
console.log("|                     Starter App                                            |");
console.log("|                                                                                   |");
if(process.env.NODE_ENV === "production") {
console.log("|         !         PRODUCTION  MODE         !                   |");
} else {
console.log("|                   DEVELOPMENT MODE                           |");
console.log("|                                                                                  |");

// Initialize database connection
const Sequelize = require('sequelize');
const sequelize = new Sequelize(process.env.POSTGRES_DB_DATABASE, process.env.POSTGRES_DB_USERNAME, process.env.POSTGRES_DB_PASSWORD, {
    host: process.env.POSTGRES_DB_HOST,
    dialect: 'postgres',

// Requirements
const express = require('express');
const bodyParser = require('body-parser');
const compression = require('compression');
const cookieParser = require('cookie-parser');
const errorHandler = require('errorhandler');
const morgan = require('morgan');
const ac = require('atlassian-connect-express');
process.env.PWD = process.env.PWD || process.cwd();
const expiry = require('static-expiry');
const hbs = require('express-hbs');
const http = require('http');
const path = require('path');
const staticDir = path.join(__dirname, 'public');
const viewsDir = __dirname + '/views';
const routes = require('./dist');
const app = express();
const addon = ac(app);
const port = addon.config.port();
const devEnv = app.get('env') === 'development';

// Setup
app.set('port', port);
app.engine('hbs', hbs.express3({partialsDir: viewsDir}));
app.set('view engine', 'hbs');
app.set('views', viewsDir);

function skipLog(req, res) {
    return !!req.url.includes("db-check");

// Middleware - Logs
app.use(morgan(devEnv ? 'dev' : 'combined', {skip: skipLog}));
// Middleware - Request Parsers
app.use(bodyParser.urlencoded({extended: false}));
// Middleware - GZip
// Middleware - General
// Middleware - Static Resource Caching
app.use(expiry(app, {dir: staticDir, debug: devEnv}));
// HBS Helper
hbs.registerHelper('furl', function(url){ return app.locals.furl(url); });

// Static Resources

// Show Errors if in Dev Mode
if (devEnv) app.use(errorHandler());

// Routes - this are the main TypeScript files which
routes(app, addon, sequelize);

addon.on('host_settings_saved', function (clientKey, data) {
    console.log(`Starter App Installed for ${clientKey} with data`, data);

// Catch Exceptions
process.on('unhandledRejection', (reason, p) => {
    console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);

// Boot
http.createServer(app).listen(port, function(){
    console.log(" - Local URL:      http://" + os.hostname() + ":" + port);
    console.log(" - Base URL:       " + process.env.BASE_URL);


I remember having a similar problem. I can’t fully remember what the problem was, but by inspecting the ACE code (in node_modules) you can see the line that’s causing the error. It’s used (AFAIK) for registering the addon on your instance in case something changes in the app descriptor (atlassian-connect.json). The way to reregister is by adding credentials.json in your project root, so the first thing I’d do is check if you have it and if the credentials inside are correct.

The next thing I’d do is check the validity of atlassian-connect (try Connect Validator).

Hope this’ll be of some use. Cheers