Intro to Serverless Notebooks Error Websocket

Hi, I tried following along with the Intro to Serverless Notebooks example on AWS (, but I’m seeing an 403 error in the console

observablehq-435:9 WebSocket connection to 'wss://<some-number>' failed: Error during WebSocket handshake: Unexpected response code: 403
open @ observablehq-435:9

which I think is happening when the notebook attempts to make the initial connection. We forked it into our team ismms-himc such that our origin is

origin = ""

I tried disabling the origin rule from the connect lambda function (that I think throws the 403 error), to temporarily allow requests from all origins but that did not help.

Do I need to publish this notebook in order for it to work? And does the notebook only allow communication to the AWS serverless services for users within our organization (using the origin URL) - if so that would be useful for our organization to make team-private stateful apps?

1 Like

Hi Nick,

I tried implementing the notebook again. I think I configured everything as instructed (will double check), but I am seeing no change in the counter. The error I see in the console is this:

			*/}var i=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable;function u(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}var c=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(o){return!1}}()?Object.assign:function(e,t){for(var n,r,o=u(e),c=1;c<arguments.length;c++){for(var s in n=Object(arguments[c])),s)&&(o[s]=n[s]);if(i){r=i(n);for(var f=0;f<r.length;f++),r[f])&&(o[r[f]]=n[r[f]])}}return o},s="function"==typeof Symbol&&Symbol.for,f=s?Symbol.for("react.element"):60103,d=s?Symbol.for("react.portal"):60106,p=s?Symbol.for("react.fragment"):60107,m=s?Symbol.for("react.strict_mode"):60108,h=s?Symbol.for("react.profiler"):60114,g=s?Symbol.for("react.provider"):60109,v=s?Symbol.for("react.context"):60110,b=s?Symbol.for("react.forward_ref"):60112,y=s?Symbol.for("react.suspense"):60113,C=s?Symbol.for("react.suspense_list"):60120,E=s?Symbol.for("react.memo"):60115,w=s?Symbol.for("react.lazy"):60116,k="function"==typeof 
... [I can't fit this all in here]

I am constantly amazed by this code. So many instances of SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED :slight_smile:

I haven’t published, afraid of I am of not understanding the ramifications. I have shared the notebook.

1 Like

Hi Aaron,

Thanks, I haven’t seen that error before. I’ll keep troubleshooting.

Hi again, Nick.

I tried Mike’s Introduction to Serverless Notebooks fresh again this morning. I have it working, and initially was seeing the same websocket error as you. After refreshing the page, however, my error disappeared – it seems that it was a hanger-on from before I changed the final bit of text that was calling to Mike’s WebSocket rather than my own (in the final increment function).

Here’s a diff to a change I proposed to Mike’s notebook flagging the needed change:

(Note that my edits don’t propose changes to Mike’s gateway ID, as the comment was on his notebook).

Have you managed to get your set-up working?

I see that you’re adapting the notebook for your specific use case. In so doing, did you modify the code from Mike’s tutorial at all? I basically just followed-along with copy and paste and everything worked.

Here’s Mike’s tutorial with a single change (swapping out his gateway ID for mine), which should show the working notebook. Also - the counter worked even before I enabled link sharing.

If you compare my notebook fork to Mike’s original, you’ll see where the change is made (it’s way down toward the end of the notebook; just a few characters long).

1 Like

Hi Aaron,

Thanks!! Switching the gateway in that increment cell got it working. I ended up making this change

socket = new WebSocket(`wss://${encodeURIComponent(gateway)}

so that way the gateway variable gets used in the increment function.

@mbostock @aaronkyle , does the API only work for users from our team Observable URL? And if we wanted to deploy a public version would we need to modify the Validate Origin of the helloConnect lambda function?


1 Like

From my understanding, the API will only work if the notebook carries your team’s subdomain (or your personal subdomain,), which was one of the configuration steps. That means that if someone forks your notebook, it will stop working (because they will be trying to call the API from their subdomain)… but as long as they just view and interact through the version you publish, it’ll work (just like Mike’s example)

Thanks @aaronkyle that makes sense.