microsoft/typescript-go · error · ErrClientError
%w: empty signature handle
Error message
%w: empty signature handle
What it means
A signature-based request passed SignatureID 0 ("empty signature handle"). SignatureID 0 is the zero value and never maps to a registered checker.Signature; resolveSignatureHandle rejects it up front as a client error. Typically the client sent a default-initialized field or took the id from a null/absent signature (getSignaturesOfType returns no entries when the type has none, and getResolvedSignature can return null when no call target resolves).
Source
Thrown at internal/api/session.go:283
if reg == nil {
return nil, fmt.Errorf("%w: type handle %d not found (no registry for project %s)", ErrClientError, handle, projectID)
}
reg.typeRegistryMu.RLock()
t, ok := reg.typeRegistry[handle]
reg.typeRegistryMu.RUnlock()
if !ok {
return nil, fmt.Errorf("%w: type handle %d not found in project registry", ErrClientError, handle)
}
return t, nil
}
// resolveSignatureHandle resolves a signature handle within the project's registry.
func (sd *snapshotData) resolveSignatureHandle(projectID ProjectID, handle SignatureID) (*checker.Signature, error) {
if handle == 0 {
return nil, fmt.Errorf("%w: empty signature handle", ErrClientError)
}
if projectID == "" {
return nil, fmt.Errorf("%w: empty project ID for signature handle %d", ErrClientError, handle)
}
sd.projectRegistriesMu.RLock()
reg := sd.projectRegistries[projectID]
sd.projectRegistriesMu.RUnlock()
if reg == nil {
return nil, fmt.Errorf("%w: signature handle %d not found (no registry for project %s)", ErrClientError, handle, projectID)
}
reg.signatureRegistryMu.RLock()
sig, ok := reg.signatureRegistry[handle]
reg.signatureRegistryMu.RUnlock()
if !ok {View on GitHub (pinned to 1bcfa18d79)
Solutions
- Null-check signature responses and absent parameter lists before issuing follow-ups
- Validate the handle is a positive integer before sending; skip the call when 0
- Make signature handles optional in the client model so 'no signature' is distinct from 'signature 0'
Example fix
// before
const sig = await call("getResolvedSignature", { snapshot, project, file, position });
await call("getTypeOfSymbol", { snapshot, project, symbol: sig?.id ? 0 : 0 }); // empty handle
// after
const sig = await call("getResolvedSignature", { snapshot, project, file, position });
if (sig) {
// sig.id is non-zero; use sig.parameters symbols etc.
} Defensive patterns
Strategy: type-guard
Validate before calling
// TS client: skip follow-ups when the signature handle is empty.
if (!signatureId) { // 0/undefined/null
return; // no signature resolved at this position
}
await call("signatureFollowUp", { snapshot, project, signature: signatureId }); Type guard
const isNonEmptySignatureHandle = (id: number | bigint | undefined | null): id is number => (typeof id === "number" || typeof id === "bigint") && id !== 0 && id > 0;
Prevention
- Null-check getResolvedSignature/getSignaturesOfType results before follow-ups
- Model signature ids as optional, not zero-defaulted
- One shared guard (id > 0) across all signature-taking request helpers
When it happens
Trigger: Passing 0 in getResolvedSignature follow-ups or signature-parameter queries; using the id of a null SignatureResponse (e.g. getResolvedSignature on a non-call expression); undefined signature field serialized as 0.
Common situations: Signature-help UIs chaining parameter/type queries without checking that a signature was found; optional fields defaulting to zero; reusing param templates.
Related errors
- %w: empty symbol handle
- %w: empty type handle
- %w: empty project ID for signature handle %d
- %w: empty project ID for type handle %d
- %w: signature handle %d not found (no registry for project %
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/f240c5dbd1fe66c2.
Report an issue: GitHub.