Skip to content

Getting PRO to work in code-server (browser) on VPS #98

Description

@ricgagliardi

I couldn't get PRO to work from my code-server web based editor. So I asked Claude to fix it. It did! So I asked it to explain it so you can make a more permanent fix. My local machine is a Mac but the VPS hosting code-server is on x86.

Thanks!


SQLite Viewer (pro) hangs on file open under code-server — diagnosis & fix

Summary

On a Linux x86-64 server running code-server, the qwtel.sqlite-viewer
extension worked fine in free mode but hung when opening a .sqlite file
after a pro license was applied
(both "Activate License Key" and "Offline
License Activation" flows). Root cause: code-server installed the wrong
platform build; the bundled native helper was a macOS/arm64 binary that
cannot run on Linux x86-64. Fix: install the linux-x64 build.

Environment

  • Host: Linux x86_64
  • Access: browser → Caddy (dev.verifyit.buzz, direct HTTPS) → code-server 127.0.0.1:8080
  • Extension: qwtel.sqlite-viewer v26.2.5
  • Firewall (ufw): inbound-only (22/80/443). Egress wide open — not involved.

Root cause

Free mode runs SQLite as WASM inside the webview (portable, works anywhere).
Applying a license switches the engine to a bundled native helper that the
extension host spawns:

out/bin/sqlite-viewer-helper      # spawned only in licensed/pro mode

The installed build was qwtel.sqlite-viewer-26.2.5-universal, and its helper was:

sqlite-viewer-helper: Mach-O 64-bit arm64 executable   (macOS Apple Silicon)
host:                 Linux x86_64
→ execve fails: "cannot execute binary file: Exec format error"

There was no Linux ELF binary in the extension at all. On file-open in pro
mode the extension spawns a helper that can never start, the webview waits
forever for query results, and the UI hangs. Identical symptom for both
activation flows because the license only flips the engine to the broken binary
— the key itself is fine.

Note: a "This content is blocked. Contact the site owner to fix the issue."
message seen while poking around was an unrelated Cloudflare block page
(from vscode.sqliteviewer.app opened in a browser), not the cause of the hang.

How to confirm (diagnostics)

# 1) Find the installed extension dir
ls -d ~/.local/share/code-server/extensions/qwtel.sqlite-viewer*

# 2) Check the native helper's architecture — THE key check
find ~/.local/share/code-server/extensions/qwtel.sqlite-viewer* \
  -name 'sqlite-viewer-helper' -exec file {} \;
#   BAD:  Mach-O ... arm64   (macOS build on a Linux host)
#   GOOD: ELF 64-bit ... x86-64

# 3) Host architecture for comparison
uname -m        # expect: x86_64

If the helper's format doesn't match the host (ELF x86-64 for Linux x86_64),
that mismatch is the bug.

Fix — install the correct platform build

cd /tmp
curl -L -o sqlite-viewer-linux-x64.vsix \
  "https://open-vsx.org/api/qwtel/sqlite-viewer/linux-x64/26.2.5/file/qwtel.sqlite-viewer-26.2.5@linux-x64.vsix"

code-server --uninstall-extension qwtel.sqlite-viewer
code-server --install-extension /tmp/sqlite-viewer-linux-x64.vsix

# Remove any leftover wrong-arch dir so code-server doesn't load a duplicate
rm -rf ~/.local/share/code-server/extensions/qwtel.sqlite-viewer-*-universal

Then reopen code-server and run Developer: Reload Window. Open a .sqlite
file — pro mode should render instead of hang. The license key stays valid; no
re-activation needed.

Pick the VSIX matching your host from Open VSX (available target platforms):
linux-x64, linux-arm64, linux-armhf, alpine-x64, alpine-arm64,
win32-x64, win32-arm64, darwin-x64, darwin-arm64.
Base URL pattern:
https://open-vsx.org/api/qwtel/sqlite-viewer/<targetPlatform>/<version>/file/qwtel.sqlite-viewer-<version>@<targetPlatform>.vsix

Verify the fix

find ~/.local/share/code-server/extensions/qwtel.sqlite-viewer* \
  -name 'sqlite-viewer-helper' -exec file {} \;
# expect exactly one: ELF 64-bit LSB executable, x86-64

For the developer (qwtel)

The failure mode is that a platform-mismatched build gets installed on a
remote/headless host and the native-helper pro path hangs silently
. Two
things would have turned a multi-hour debug into seconds:

  1. Fail loudly instead of hanging. When spawn(bin/sqlite-viewer-helper)
    errors (EACCES, ENOENT, Exec format error/ENOEXEC) or the child
    exits before the handshake, surface an error in the webview / a
    showErrorMessage, rather than leaving the webview awaiting worker
    messages forever. A spawn error + startup timeout with a clear message
    ("native helper failed to start — wrong platform build?") is enough.

  2. Detect arch/platform mismatch at activation. On licensed activation,
    check that the shipped helper matches process.platform/process.arch
    (or just probe-run it) and, if not, tell the user to install the
    <targetPlatform> build. The -universal build carrying a single
    platform's binary is the trap.

Symptom seen by users: pro activation succeeds, then every .sqlite open
hangs with no error; free/WASM mode works. Repro: install a build whose
out/bin/sqlite-viewer-helper doesn't match the host arch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions