I updated to Portal 0.67.0 and now nothing shows up in my VS Code Portal windowsβnothing at all: just blank. If I roll back to 0.66.0, it works.
Happy to help debug it, if you give me some pointers on what to look for...
It's probably this commit: https://github.com/djblue/portal/commit/b0bd023dcbb4c02afb07ce9e76f421f9a17de544. The default for http-kit is to bind to the public interface 0.0.0.0. I had always intend for portal to bind to the private interface by default and for users to explicitly opt into the risk of binding to the public interface. The easy fix is to pass :host "0.0.0.0" to revert back to the old behavior. Does you setup require biding to the public interface?
No idea about networking stuff... let me see if I can make that fix work.
you can pass it to start or open
That's a lot more complicated for me to test than it sounds π
And, yes, for my qa/production connections, I strongly suspect it needs to bind to the public interface.
I thought it gets peroxided via ssh though
Adding :host "0.0.0.0" to the open call doesn't seem to work.
I can't get it to work locally, with that added.
I added :host "0.0.0.0" to both of those open` calls. Still blank.
The server may already be started, let me check real quick
I'm not sure what's going on. If we can't figure out what's wrong, I don't mind changing the default back to 0.0.0.0 . It's still a bit odd to me why the SSH tunnel can't proxy localhost bound servers. I'll need to look into that.
I'm not even trying that SSH tunnel. It doesn't work locally any more in VS Code.
The two windows open in VS Code from my local REPL-connected process, but they are completely blank.
Ohh, that's even more odd π€
What operating system are you on?
VS Code on Windows, process running on WSL2.
(so it's probably treated as remote, even locally?)
The vscode wsl extension does a pretty good job of proxying ports, especially for extensions. I sometimes work in WSL2 and didn't run into any issues during testing. Are you opening the UI via the vscode launcher?
I'll play around some more after work to see if I can find a fix, otherwise I'll probably revert the default back. Sorry for the inconvenience.
Sorry that the fix doesn't seem obvious π Were you able to repro?
I haven't tried to reproduce yet, what WSL2 vm are you using, Ubuntu 24?
Ubuntu 20.04. Still. Sorry π
One day I'll upgrade π
Hang on, I rolled back to 0.66.0 so I could actually work... will take me a bit to go back to 0.67.0 to test that...
I have 26 ports under thatβhow would I know which is Portal?
All good. I tried a fresh 20.04 ubuntu image on WSL2 and can't reproduce.
(:port (portal.api/start nil)) should return the http port I think
I do wonder if for some reason the port will only be forwarded in your setup when the server is bound to a public interface π€
I restarted VS Code. Now it thinks there are 28 ports active. I haven't started a REPL yet.
What vscode version are you running?
Mine looks to be 7 months old. I'll see if bumping that can reproduce π
Latest VS Code. Latest Calva. Nightly LSP/Kondo. I'm always on the very latest version of everything. Except Ubuntu π
Nope, bumping to latest vscode still works for me. Do you mind clearing all your ports and reloading vscode to see if that's the issue, perhaps too many mapped ports? I'm assuming you didn't manually enter all those ports and the vsocde did that for you.
What do you mean by "clearing all your ports"?
I never manually add any ports.
If you open the ports tab you can hover over the port column and remove it.
If I manually start Portal, how do I then open a Portal window in VS Code given the result of that start call?
user=> (require 'portal.api)
nil
user=> (portal.api/start {:host "0.0.0.0"})
{:http-server #object[org.httpkit.server.HttpServer 0x69cfbd8d "org.httpkit.server.HttpServer@69cfbd8d"], :port 38347, :host "0.0.0.0"}Ohh, since portal only has a single server instance, any port/host info passed to open will be ignore if the server is already running.
(I'm testing the :host option just in case it provides a workaround)
Right, I get that. I'm trying to debug this.
Okay, I did this in the REPL (where I started the server with :host). Portal window opened completely blank again.
user=> (portal.api/open {:launcher :vs-code})
{:session-id #uuid "a0b26de0-e5d0-45f2-8932-3046caddea5c"}I wanted to do that to make sure I had the port number on hand.
(portal.api/url (portal.api/open {:launcher false})) what does this return?
Port 38347 shows up as π’ in the Ports tab, and it's the Java process that my REPL is running.
I quit the REPL, I have no java processes running. That Ports tab still shows that process as green and user forwarded.
I restarted my REPL. I started Portal again (with :host) and that command gave me this URL: http://0.0.0.0:42935?c59c6df4-2023-49cb-a1c4-585b0072d9c5
I'm going to test this with :host "localhost", and then roll back to 0.66.0 and re-test.
user=> (require 'portal.api)
nil
user=> (portal.api/start {:host "localhost"})
{:http-server #object[org.httpkit.server.HttpServer 0x7c71e3fa "org.httpkit.server.HttpServer@7c71e3fa"], :port 35231, :host "localhost"}
user=> (portal.api/url (portal.api/open {:launcher false}))
""
That's with 0.67.0.Ok, I think I've found a way to reproduce
When is the vs-code.edn file created?
When the vscode portal extension is loaded
Ah, okay. So I blew it away and of course now I can't start Portal... just a sec...
(portal.api/start {:host "127.0.0.1"}) Do you mind seeing if starting with this host works?
I'm testing 0.66.0. I'll have to go back to 0.67.0 π
Sorry for all the chaos π
user=> (require 'portal.api)
nil
user=> (portal.api/start {:host "127.0.0.1"})
{:http-server #object[org.httpkit.server.HttpServer 0x1b2ebf00 "org.httpkit.server.HttpServer@1b2ebf00"], :port 43601, :host "127.0.0.1"}
user=> (portal.api/open {:launcher :vs-code})
{:session-id #uuid "b02b5044-1f76-4817-8e0b-82c5d76a0c68"}
Portal window opens blank.And 43601 is listed in the ports tab?
Yes, user forwarded.
Gotcha. Also, I think the :host "0.0.0.0" fix won't work for WSL2 since the portal server is not accessible on windows via 0.0.0.0 , only localhost. I guess the way it was working previously was the server in the linux vm was binding to 0.0.0.0 and the window vscode process was still hitting localhost which WSL2 will port forward into the vm.
Yup.
Okay, I'll stop bothering you for now and do some research to see if I can figure out a way around this.
What were the other changes between 0.66.0 and 0.67.0?
(and you're not bothering me at all, at this point π )
https://github.com/djblue/portal/compare/0.66.0...0.67.0 The only other thing that got updated was removing some debug code the never runs for users anyway.
Ok... this might be interesting...
user=> (require 'portal.api)
nil
user=> (portal.api/start {:host "0.0.0.0"})
{:http-server #object[org.httpkit.server.HttpServer 0x7c71e3fa "org.httpkit.server.HttpServer@7c71e3fa"], :port 45235, :host "0.0.0.0"}
user=> (portal.api/open {:launcher :vs-code})
{:session-id #uuid "908ea2db-7d49-4a0d-9cf0-1f42acaa7728"}
user=> (portal.api/url *1
#_=> )
""
user=>
And then I opened that URL in a VS Code internal browser using localhost (instead) and it shows the browser version of Portal.And I can go to Edge on Windows, and that URL works.
(I can only have one of those browsers connected at a time tho', which is expected, right?)
Yes, unless you change the uuid session
I closed those browsers, and now I'm getting this exception in the REPL, every few seconds
Wed Jul 22 21:47:05 UTC 2026 [] ERROR - handle websocket frame org.httpkit.server.Frame$TextFrame@6b2bd220
java.lang.NullPointerException: Cannot invoke "clojure.lang.IFn.invoke(Object)" because "this.send_BANG_" is null
at portal.runtime.rpc$on_receive$on_done__5527.invoke(rpc.cljc:36)
at portal.runtime$invoke.invokeStatic(runtime.cljc:511)
at portal.runtime$invoke.invoke(runtime.cljc:504)
at clojure.lang.Var.invoke(Var.java:390)
at portal.runtime.rpc$on_receive.invokeStatic(rpc.cljc:41)
at portal.runtime.rpc$on_receive.invoke(rpc.cljc:30)
at portal.runtime.jvm.server$eval5545$fn__5546$fn__5547.invoke(server.clj:31)Ohh, it works for me because I have the following in my .wslconfig
[wsl2]
networkingMode=mirroredRemind me: where is that file?
(I rarely touch it, but I have stuff configured it)
I'm not 100% sure but I know it's in my windows home directory and it had those two lines π And when I remove those two lines, it breaks. So I think I've finally figured out what's different between our machines.
I don't think users should need to have that config for Portal to work, so this is a bug that should be fixed on the Portal side.
Here's what I've had to put in mine:
(!2007)-> cat /mnt/c/Users/seanc/.wslconfig
[wsl2]
memory=20GB
localhostForwarding=true
#networkingMode=mirrored
#dnsTunneling=true
Note that I had to turn OFF mirroring and tunneling for vague network-related reasons here.I have to run a cloudflared process to prevent my ISP sniffing (and breaking) DNS lookup from the WSL2 side π
Should be fixed in https://github.com/djblue/portal/releases/tag/0.67.1
Thanks. Will move back to my main computer now and go test that...
@djblue Thanks, Chris! It works again! π
Awesome, sorry again for the inconvenience and thanks for helping me narrow down the issue π
So, I'm curious why :host "0.0.0.0" didn't seem to work?
It does in terms of making the portal repl server accessible, but the web view in vscode still needs to go through local host to reach it π
The fix was to essentially revert to the old behavior for WSL
Oh, so if you specify :host, it fixed one thing but broke another?
Exactly! Which is why I thought I reproduced it initially