{"record":{"id":"3404b503c625b6dc","repo":"wavetermdev/waveterm","slug":"error-parsing-token-w","errorCode":null,"errorMessage":"error parsing token: %w","messagePattern":"error parsing token: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshutil/wshutil.go","lineNumber":363,"sourceCode":"\t\t\tconn.Close()\n\t\t\tclose(proxy.FromRemoteCh)\n\t\t\tclose(proxy.ToRemoteCh)\n\t\t\tlinkId := linkIdContainer.Load()\n\t\t\tif linkId != baseds.NoLinkId {\n\t\t\t\tDefaultRouter.UnregisterLink(baseds.LinkId(linkId))\n\t\t\t}\n\t\t}()\n\t\tAdaptStreamToMsgCh(conn, proxy.FromRemoteCh, readCallback)\n\t}()\n\tlinkId := DefaultRouter.RegisterUntrustedLink(proxy)\n\tlinkIdContainer.Store(int32(linkId))\n}\n\n// only for use on client\nfunc ExtractUnverifiedRpcContext(tokenStr string) (*wshrpc.RpcContext, error) {\n\ttoken, _, err := new(jwt.Parser).ParseUnverified(tokenStr, &wavejwt.WaveJwtClaims{})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing token: %w\", err)\n\t}\n\tclaims, ok := token.Claims.(*wavejwt.WaveJwtClaims)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"error getting claims from token\")\n\t}\n\treturn claimsToRpcCtx(claims), nil\n}\n\n// only for use on client\nfunc ExtractUnverifiedSocketName(tokenStr string) (string, error) {\n\ttoken, _, err := new(jwt.Parser).ParseUnverified(tokenStr, &wavejwt.WaveJwtClaims{})\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error parsing token: %w\", err)\n\t}\n\tclaims, ok := token.Claims.(*wavejwt.WaveJwtClaims)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"error getting claims from token\")\n\t}","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshutil/wshutil.go#L345-L381","documentation":"ExtractUnverifiedRpcContext decodes a Wave JWT token into an RpcContext without verifying its signature. This error wraps any failure from jwt.Parser.ParseUnverified, meaning the token string could not be parsed as a JWT at all (malformed structure, wrong segment count, invalid base64 or JSON).","triggerScenarios":"Calling ExtractUnverifiedRpcContext with an empty string, a truncated or corrupted token, a token that is not a JWT (e.g. an opaque secret or a different token format), or a token whose claims JSON does not match wavejwt.WaveJwtClaims.","commonSituations":"Stale or hand-edited connection tokens in config; passing the wrong env/config value (e.g. the socket name instead of the token); tokens regenerated by a newer server version while an old client reads cached ones; shell quoting mangling the token on the command line.","solutions":["Regenerate the connection token from the running Wave server (wsh server) so the client reads a fresh, valid token","Verify the string being passed is the JWT (three dot-separated base64 segments), not the socket name or another config value","Inspect the wrapped inner error (%w) with errors.Unwrap to see the exact JWT parse failure (e.g. 'token contains an invalid number of segments')","If the token comes from a file or env var, check for whitespace/newline corruption or truncation"],"exampleFix":"// before\nctx, err := wshutil.ExtractUnverifiedRpcContext(os.Getenv(\"WS_TOKEN\"))\n// after\ntokenStr := strings.TrimSpace(os.Getenv(\"WS_TOKEN\"))\nif tokenStr == \"\" || strings.Count(tokenStr, \".\") != 2 {\n    return fmt.Errorf(\"invalid WSH token: regenerate via 'wsh server'\")\n}\nctx, err := wshutil.ExtractUnverifiedRpcContext(tokenStr)","handlingStrategy":"validation","validationCode":"func looksLikeJwt(s string) bool {\n    s = strings.TrimSpace(s)\n    parts := strings.Split(s, \".\")\n    if len(parts) != 3 {\n        return false\n    }\n    for _, p := range parts {\n        if p == \"\" { return false }\n        if _, err := base64.RawURLEncoding.DecodeString(p); err != nil { return false }\n    }\n    return true\n}","typeGuard":null,"tryCatchPattern":"ctx, err := wshutil.ExtractUnverifiedRpcContext(tokenStr)\nif err != nil {\n    return fmt.Errorf(\"invalid wsh token (regenerate with 'wsh server'): %w\", err)\n}","preventionTips":["Always source tokens directly from 'wsh server' output or the server's config file","Trim whitespace/newlines when reading tokens from env vars or files","Sanity-check the three-segment JWT shape before parsing","Keep client and server on the same Wave version"],"tags":["jwt","token-parse","wsh"],"backgroundTag":"jwt-token-invalid","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}