wavetermdev/waveterm · error

sock claim is missing or invalid

Error message

sock claim is missing or invalid

What it means

The token parsed and claims were of the correct type, but the 'sock' claim is empty, so there is no socket path to return. Wave requires every wsh connection token to carry the domain socket path it was issued for.

Source

Thrown at pkg/wshutil/wshutil.go:384

	if !ok {
		return nil, fmt.Errorf("error getting claims from token")
	}
	return claimsToRpcCtx(claims), nil
}

// only for use on client
func ExtractUnverifiedSocketName(tokenStr string) (string, error) {
	token, _, err := new(jwt.Parser).ParseUnverified(tokenStr, &wavejwt.WaveJwtClaims{})
	if err != nil {
		return "", fmt.Errorf("error parsing token: %w", err)
	}
	claims, ok := token.Claims.(*wavejwt.WaveJwtClaims)
	if !ok {
		return "", fmt.Errorf("error getting claims from token")
	}
	sockName := claims.Sock
	if sockName == "" {
		return "", fmt.Errorf("sock claim is missing or invalid")
	}
	sockName = wavebase.ExpandHomeDirSafe(sockName)
	return sockName, nil
}

func getShell() string {
	if runtime.GOOS == "darwin" {
		return shellutil.GetMacUserShell()
	}
	shell := os.Getenv("SHELL")
	if shell == "" {
		return "/bin/bash"
	}
	return strings.TrimSpace(shell)
}

func GetInfo() wshrpc.RemoteInfo {
	return wshrpc.RemoteInfo{

View on GitHub (pinned to a4447c1563)

Solutions

  1. Regenerate the connection token from the actual Wave server ('wsh server') so the sock claim is populated
  2. Verify with a JWT decoder (e.g. jwt.io) that the payload contains a non-empty 'sock' field
  3. Ensure client and server are the same Wave version

Example fix

// before
sock, err := wshutil.ExtractUnverifiedSocketName(oldToken)
// after
// regenerate the token from the running server, then:
out, _ := exec.Command("wsh", "server", "--token-only").Output()
sock, err := wshutil.ExtractUnverifiedSocketName(strings.TrimSpace(string(out)))
Defensive patterns

Strategy: validation

Validate before calling

func tokenHasSock(tokenStr string) bool {
    parts := strings.Split(strings.TrimSpace(tokenStr), ".")
    if len(parts) != 3 { return false }
    payload, err := base64.RawURLEncoding.DecodeString(parts[1])
    if err != nil { return false }
    var c struct{ Sock string `json:"sock"` }
    return json.Unmarshal(payload, &c) == nil && c.Sock != ""
}

Try / catch

sockName, err := wshutil.ExtractUnverifiedSocketName(tokenStr)
if err != nil {
    return fmt.Errorf("token lacks sock claim; reissue via 'wsh server': %w", err)
}

Prevention

When it happens

Trigger: Calling ExtractUnverifiedSocketName with a Wave JWT that lacks a non-empty sock claim — e.g. a token minted by custom code, an old token format, or a claims struct where sock was never set.

Common situations: Hand-built or third-party-minted tokens; server upgrade changing token contents while a cached old token is reused; copying a token from a different tool.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/60a2f4bd09224e43. Report an issue: GitHub.