windmill-labs/windmill · error · GitHubAppError
UNKNOWN_ERROR
UNKNOWN_ERROR
Error message
No JWT token received from server
What it means
After GitSyncService.exportInstallation() returns, exportInstallation() checks that the server response contains a jwt_token field and throws this UNKNOWN_ERROR if it is missing/empty. It guards against a server or proxy responding 2xx with an unexpected body, before the token is copied to the clipboard.
Source
Thrown at frontend/src/lib/githubApp.ts:333
currentWorkspace: string,
installationId: number
): Promise<void> {
// Input validation
if (!currentWorkspace) {
throw createGitHubAppError('Workspace is required', 'VALIDATION_ERROR')
}
if (!installationId || installationId <= 0) {
throw createGitHubAppError('Valid installation ID is required', 'VALIDATION_ERROR')
}
try {
const response = await GitSyncService.exportInstallation({
workspace: currentWorkspace,
installationId: installationId
})
if (!response.jwt_token) {
throw createGitHubAppError('No JWT token received from server', 'UNKNOWN_ERROR')
}
const jwtToken = response.jwt_token
// Copy to clipboard with fallback for unsecure contexts
if (navigator.clipboard && navigator.clipboard.writeText) {
await navigator.clipboard.writeText(jwtToken)
sendUserToast(
'JWT token copied to clipboard. This token is sensitive and should be kept secret!',
false,
undefined,
undefined,
10000
)
} else {
// Fallback: show the token in the toast for manual copying
sendUserToast(
`JWT token (copy manually): ${jwtToken}`,View on GitHub (pinned to e474e8803c)
Solutions
- Verify frontend and backend versions match and the git_sync export endpoint returns { jwt_token: ... }.
- Inspect the raw HTTP response (network tab) to see what the server actually returned.
- Check for a reverse proxy or gateway altering the response body/status.
- Log out / re-login to rule out a stale session producing a degraded response.
Example fix
// before
const response = await GitSyncService.exportInstallation({ workspace, installationId })
copyToClipboard(response.jwt_token)
// after
const response = await GitSyncService.exportInstallation({ workspace, installationId })
if (!response?.jwt_token) throw new Error('Server returned no jwt_token')
copyToClipboard(response.jwt_token) Defensive patterns
Strategy: try-catch
Type guard
function hasJwtToken(r: unknown): r is { jwt_token: string } {
return typeof r === 'object' && r !== null && typeof (r as any).jwt_token === 'string' && (r as any).jwt_token.length > 0
} Try / catch
try {
await exportInstallation(workspace, installationId)
} catch (e) {
if (e?.message?.includes('No JWT token')) {
toast.error('Server did not return a token — check frontend/backend versions and proxy')
} else throw e
} Prevention
- Keep frontend and backend versions in sync.
- Add an API response schema check (zod) for exportInstallation responses.
- Watch for reverse proxies rewriting JSON bodies in dev/test environments.
When it happens
Trigger: The backend endpoint for git_sync app installation export returns 200 but with a body lacking jwt_token — e.g. an API version mismatch where the field was renamed, an HTML error page served by a reverse proxy with status 200, or the server serializing an empty object.
Common situations: Frontend and backend deployed at mismatched versions (field renamed/removed); a dev proxy intercepting the request; the instance behind an auth gateway that rewrites responses; backend bug returning success without generating the token.
Related errors
- VALIDATION_ERROR
- string(res.Body)
- External JWT auth is not open source
- could not create initial server dir
- connection error: ${err instanceof Error ? err.message : err
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/12a30b51f3bd1715.
Report an issue: GitHub.