microsoft/typescript-go · error
ErrClientError
ErrClientError
Error message
api: client error
What it means
Sentinel error wrapped by dozens of session-level failures caused by the client's view being stale rather than the request being malformed: unknown snapshot/symbol/type/signature/node handles, project not found, project without a program, source file not found, unreadable config. errors.Is(err, api.ErrClientError) means: refresh your state and retry, do not blame the payload shape.
Source
Thrown at internal/api/proto.go:25
"github.com/microsoft/typescript-go/internal/ast"
"github.com/microsoft/typescript-go/internal/checker"
"github.com/microsoft/typescript-go/internal/collections"
"github.com/microsoft/typescript-go/internal/core"
"github.com/microsoft/typescript-go/internal/diagnostics"
"github.com/microsoft/typescript-go/internal/jsnum"
"github.com/microsoft/typescript-go/internal/json"
"github.com/microsoft/typescript-go/internal/locale"
"github.com/microsoft/typescript-go/internal/ls/lsconv"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/packagejson"
"github.com/microsoft/typescript-go/internal/project"
"github.com/microsoft/typescript-go/internal/tsoptions"
"github.com/microsoft/typescript-go/internal/tspath"
)
var (
ErrInvalidRequest = errors.New("api: invalid request")
ErrClientError = errors.New("api: client error")
)
type Method string
type (
SnapshotID uint64
ProjectID string
SymbolID uint64
TypeID uint32
SignatureID uint64
NodeHandle string
)
func ProjectHandle(p *project.Project) ProjectID {
return ProjectID(p.ID())
}
func SymbolHandle(symbol *ast.Symbol) SymbolID {View on GitHub (pinned to 1bcfa18d79)
Solutions
- Re-acquire current IDs (open a fresh snapshot) and retry the request
- Send filesChanged/open/close notifications so server snapshots track your edits
- Wait for project/program readiness before issuing dependent calls
- For deleted files, notify the deletion so the server stops holding handles into them
Example fix
// before
res, err := session.GetDiagnostics(ctx, oldSnapshotID, file)
// after
if errors.Is(err, api.ErrClientError) {
snap, _ := session.OpenSnapshot(ctx, file)
res, err = session.GetDiagnostics(ctx, snap.ID, file)
} Defensive patterns
Strategy: retry
Type guard
func isClientError(err error) bool { return errors.Is(err, api.ErrClientError) } Try / catch
res, err := session.Something(ctx, params)
if errors.Is(err, api.ErrClientError) {
// stale handles / unknown project / missing file: refresh state and retry once
snap, rerr := session.Refresh(ctx)
if rerr == nil {
res, err = session.Something(ctx, params)
}
}
return res, err Prevention
- Re-acquire snapshot/handle IDs after every file change
- Send filesChanged notifications so the server tracks edits
- Wait for project load before issuing dependent requests
- Treat ErrClientError as retriable-with-refresh, never as a payload bug
When it happens
Trigger: Using a SnapshotID after the server invalidated it; passing a NodeHandle from an older snapshot; requesting a file not loaded in the project; asking about a project before its program is built; a handle registry miss after project reload.
Common situations: Long-lived editor sessions where documents change under cached IDs; reconnecting without re-initializing; racing project load; deleting files without notifying the server.
Related errors
- ErrInvalidRequest
- %w: project %s not found
- %w: symbol handle %d not found in snapshot registry
- %w: type handle %d not found (no registry for project %s)
- %w: type handle %d not found in project registry
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/3537f194a2f1f3bc.
Report an issue: GitHub.