Expected non-empty string for undefined

Hi there,

I have tried to use: coda auth pack.ts
I have inserted the oauth client ID and secret through the setup process.
Then I have completed the flow within the browser.
At the end I was redirected to: http://localhost/oauth?code=code&scope=scope as expected.

But it seems that the .coda-credentials.json was not updated, I can only see:
{
“credentials”: {
“clientId”: “client_id”,
“clientSecret”: “client_secret
}
}
Shouldn’t there be somewhere the authorization code and the scope?
Because when I use: coda execute pack.ts Hello “World” --fetch I get the following error.
Can I manually paste the authorization code into the right place?

ERROR:

Error: Expected non-empty string for undefined
at ensureNonEmptyString (/usr/local/nvm/versions/node/v12.14.1/lib/node_modules/@codahq/packs-sdk/dist/helpers/ensure.js:41:15)
at AuthenticatingFetcher._applyAuthentication (/usr/local/nvm/versions/node/v12.14.1/lib/node_modules/@codahq/packs-sdk/dist/testing/fetcher.js:281:99)
at AuthenticatingFetcher.fetch (/usr/local/nvm/versions/node/v12.14.1/lib/node_modules/@codahq/packs-sdk/dist/testing/fetcher.js:46:57)
at stub (/usr/local/nvm/versions/node/v12.14.1/lib/node_modules/@codahq/packs-sdk/dist/runtime/bootstrap/index.js:76:30)
{
message: ‘Expected non-empty string for undefined’,
name: ‘Error’
}

Thank you in advance.

Is there any console output from the coda auth command? It looks like the client ID and secret are stored in the file once the flow starts, and my guess is that the token exchange failed for some reason, leaving the file in this half-complete state.

There is no output, the process did not end. I can only assume that the reason for this behavior is that I am using Google Cloud Shell as my development environment. Within Google Cloud Shell there is no localhost (which is used as oauth callback URL), instead a preview site is created on the fly. Therefore I have used XAMPP to turn on localhost. But I assume that Coda SDK and localhost need to be within in the same environment.

As a workaround I have tried to install the Coda SDK on my local machine:
npm i @codahq/packs-sdk

The result is always the same (tried within Git Bash and WSL 2):

npm WARN deprecated request-promise-native@1.0.9: request-promise-native has been deprecated because it extends
the now deprecated request package, see https://github.com/request/request/issues/3142
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See There’s Math.random(), and then there’s Math.random() · V8 for details.
npm WARN deprecated request@2.88.2: request has been deprecated, see…
npm ERR! code 1
npm ERR! path /mnt/c/Users/User/Downloads/ga-pack-local/node_modules/isolated-vm
npm ERR! command failed
npm ERR! command sh -c node-gyp rebuild --release -j 4
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp info using node-gyp@8.3.0
npm ERR! gyp info using node@16.13.1 | linux | x64
npm ERR! gyp info find Python using Python version 3.8.10 found at “/usr/bin/python3”
npm ERR! gyp info spawn /usr/bin/python3
npm ERR! gyp info spawn args [
npm ERR! gyp info spawn args ‘/home/jk/.nvm/versions/node/v16.13.1/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py’,
npm ERR! gyp info spawn args ‘binding.gyp’,
npm ERR! gyp info spawn args ‘-f’,
npm ERR! gyp info spawn args ‘make’,
npm ERR! gyp info spawn args ‘-I’,
npm ERR! gyp info spawn args ‘/mnt/c/Users/User/Downloads/ga-pack-local/node_modules/isolated-vm/build/config.gypi’,
npm ERR! gyp info spawn args ‘-I’,
npm ERR! gyp info spawn args ‘/home/jk/.nvm/versions/node/v16.13.1/lib/node_modules/npm/node_modules/node-gyp/addon.gypi’,
npm ERR! gyp info spawn args ‘-I’,
npm ERR! gyp info spawn args ‘/home/jk/.cache/node-gyp/16.13.1/include/node/common.gypi’,
npm ERR! gyp info spawn args ‘-Dlibrary=shared_library’,
npm ERR! gyp info spawn args ‘-Dvisibility=default’,
npm ERR! gyp info spawn args ‘-Dnode_root_dir=/home/jk/.cache/node-gyp/16.13.1’,
npm ERR! gyp info spawn args ‘-Dnode_gyp_dir=/home/jk/.nvm/versions/node/v16.13.1/lib/node_modules/npm/node_modules/node-gyp’,
npm ERR! gyp info spawn args ‘-Dnode_lib_file=/home/jk/.cache/node-gyp/16.13.1/<(target_arch)/node.lib’,
npm ERR! gyp info spawn args ‘-Dmodule_root_dir=/mnt/c/Users/User/Downloads/ga-pack-local/node_modules/isolated-vm’,
npm ERR! gyp info spawn args ‘-Dnode_engine=v8’,
npm ERR! gyp info spawn args ‘–depth=.’,
npm ERR! gyp info spawn args ‘–no-parallel’,
npm ERR! gyp info spawn args ‘–generator-output’,
npm ERR! gyp info spawn args ‘build’,
npm ERR! gyp info spawn args ‘-Goutput_dir=.’
npm ERR! gyp info spawn args ]
npm ERR! gyp ERR! build error
npm ERR! gyp ERR! stack Error: not found: make
npm ERR! gyp ERR! stack at getNotFoundError (/home/jk/.nvm/versions/node/v16.13.1/lib/node_modules/npm/node_modules/which/which.js:10:17)
npm ERR! gyp ERR! stack at /home/jk/.nvm/versions/node/v16.13.1/lib/node_modules/npm/node_modules/which/which.js:57:18
npm ERR! gyp ERR! stack at new Promise ()
npm ERR! gyp ERR! stack at step (/home/jk/.nvm/versions/node/v16.13.1/lib/node_modules/npm/node_modules/which/which.js:54:21)
npm ERR! gyp ERR! stack at /home/jk/.nvm/versions/node/v16.13.1/lib/node_modules/npm/node_modules/which/which.js:71:22
npm ERR! gyp ERR! stack at new Promise ()
npm ERR! gyp ERR! stack at subStep (/home/jk/.nvm/versions/node/v16.13.1/lib/node_modules/npm/node_modules/which/which.js:69:33)
npm ERR! gyp ERR! stack at /home/jk/.nvm/versions/node/v16.13.1/lib/node_modules/npm/node_modules/which/which.js:80:22
npm ERR! gyp ERR! stack at /home/jk/.nvm/versions/node/v16.13.1/lib/node_modules/npm/node_modules/isexe/index.js:42:5
npm ERR! gyp ERR! stack at /home/jk/.nvm/versions/node/v16.13.1/lib/node_modules/npm/node_modules/isexe/mode.js:8:5
npm ERR! gyp ERR! System Linux 5.10.16.3-microsoft-standard-WSL2
npm ERR! gyp ERR! command “/home/jk/.nvm/versions/node/v16.13.1/bin/node” “/home/jk/.nvm/versions/node/v16.13.1/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js” “rebuild” “–release” “-j” “4”
npm ERR! gyp ERR! cwd /mnt/c/Users/User/Downloads/ga-pack-local/node_modules/isolated-vm
npm ERR! gyp ERR! node -v v16.13.1
npm ERR! gyp ERR! node-gyp -v v8.3.0
npm ERR! gyp ERR! not ok

npm ERR! A complete log of this run can be found in:
npm ERR! /home/jk/.npm/_logs/2022-01-05T15_50_30_344Z-debug.log

Ya, I don’t think coda auth will work with Google Cloud Shell at the moment, since it assumes the CLI command is running on your local machine. I’ll file a feature request to see if we can support configurable hosts for the redirect URL.

As for install the SDK on WSL, it looks like the isolated-vm package we rely on has it’s own requirements that aren’t installed by default on the VM. The list of requirements is available here:

I had an Ubuntu VM and following their directions I was able to get the SDK to install properly. I’ll update our documentation to mention this.

Thank you for the pointer and your help.

This worked for me for WSL 2:
Ubuntu users should run: sudo apt-get install python g++ build-essential

I have now also installed the additional dependencies for Windows.
Just a hint, if someone else is stumbling over this post:
You need to install MS Build Tools 2017 and not 2019 (the link within the node-gyp README.md is pointing to the 2019 version).

@Eric_Koleda It seems that the Google access token expires every hour, therefore I need to periodically use: coda auth pack.ts
It is OK to do it this way, but maybe it could be automated. Just an idea.

I’m glad you were able to get it working, and thanks for sharing those tips.

Regarding the auth expiring, if you have a refresh token it should be refreshing it automatically. Ensure you OAuth2 config includes the following, so that you get a refresh token:

  additionalParams: {
    access_type: "offline",
    prompt: "consent",
  },

Thank you it worked adding these settings :+1:

@Eric_Koleda The settings above work for my local environment, but when I test the pack within a doc, I always have to refresh my login via: Insert > Packs & import > My Pack > Settings > … > Sign in again.

Are there any futher settings needed? Thank you.

No, that should be enough. When you click Sign in again are you presented with an approval prompt from Google, or does it just auto-approve? Google will only send a refresh token when you get an approval prompt (which is why I recommended prompt: "consent").

Yes there is an approval prompt.

Strange. Can you post the code you have for setting up user auth?

Sure, please see below.

pack.setUserAuthentication({
  type: coda.AuthenticationType.OAuth2,
  authorizationUrl: "https://accounts.google.com/o/oauth2/auth",
  tokenUrl: "https://accounts.google.com/o/oauth2/token",
  scopes: ["https://www.googleapis.com/auth/analytics.readonly"],
  additionalParams: {
    access_type: "offline",
    prompt: "consent"
  }
});