microsoft/typescript-go · error · ErrClientError

%w: signature handle %d not found (no registry for project %

Error message

%w: signature handle %d not found (no registry for project %s)

What it means

resolveSignatureHandle found no projectRegistryData for the ProjectID: "signature handle N not found (no registry for project P)". A project's signature registry is created lazily when the first signature is registered in that project within this snapshot, so this error means no signature-producing call has run in that project here - overwhelmingly caused by a wrong or stale ProjectID paired with the handle.

Source

Thrown at internal/api/session.go:294

	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 {
		return nil, fmt.Errorf("%w: signature handle %d not found in project registry", ErrClientError, handle)
	}

	return sig, nil
}

// newSignatureResponse registers a signature in the project's registry and returns the response.
func (sd *snapshotData) newSignatureResponse(projectID ProjectID, sig *checker.Signature) *SignatureResponse {
	if sig == nil {
		return nil
	}

View on GitHub (pinned to 1bcfa18d79)

Solutions

  1. Re-run the signature query (getSignaturesOfType / getResolvedSignature) in the current snapshot and use the freshly returned handle
  2. Invalidate signature caches on snapshot change or release
  3. Confirm the project handle itself is current for the snapshot

Example fix

// before
await call("signatureFollowUp", { snapshot, project: oldProject, signature: cachedSig }); // no registry

// after
const sig = await call("getResolvedSignature", { snapshot, project, file, position });
if (sig) await call("signatureFollowUp", { snapshot, project, signature: sig.id });
Defensive patterns

Strategy: validation

Validate before calling

// TS client: validate scope before sending.
const key = `${snapshot}:${project}`;
if (!signatureRegistriesSeen.has(key)) {
  throw new Error(`no signature registry for ${key}; re-run getResolvedSignature/getSignaturesOfType first`);
}
await call("signatureFollowUp", { snapshot, project, signature });

Type guard

const isScopedSignatureHandle = (h: { snapshot: bigint; project: string; id: number }, cur: bigint): boolean =>
  h.snapshot === cur && h.project.length > 0 && h.id > 0;

Prevention

When it happens

Trigger: Signature handle sent with a project handle from a different snapshot; signature from project A paired with project B's handle; querying a project that has never returned signatures in this snapshot with a fabricated/foreign signature id.

Common situations: Cached {project, signature} pairs surviving an updateSnapshot; cross-project completion/signature-help flows mixing handles; session restart invalidating registries.

Related errors


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