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

  1. Re-acquire current IDs (open a fresh snapshot) and retry the request
  2. Send filesChanged/open/close notifications so server snapshots track your edits
  3. Wait for project/program readiness before issuing dependent calls
  4. 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

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


AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16). Data as JSON: /api/errors/3537f194a2f1f3bc. Report an issue: GitHub.