microsoft/typescript-go · error

unknown method: %s

Error message

unknown method: %s

What it means

The request's method string matched no case in Session.HandleRequest's dispatch switch and no unmarshaler in proto.go, so the session rejects it with a plain error (no sentinel wrapper). Note that getServerTiming and resetServerTiming are handled by the connection layer, not the session, so they also fail if routed to a raw session handler.

Source

Thrown at internal/api/session.go:865

		return s.handleGetGlobalDiagnostics(ctx, parsed.(*GetProjectDiagnosticsParams))
	case string(MethodGetConfigFileParsingDiagnostics):
		return s.handleGetConfigFileParsingDiagnostics(ctx, parsed.(*GetProjectDiagnosticsParams))
	case string(MethodStartCPUProfile):
		return s.handleStartCPUProfile(ctx, parsed.(*ProfileParams))
	case string(MethodStopCPUProfile):
		return s.handleStopCPUProfile(ctx)
	case string(MethodSaveHeapProfile):
		return s.handleSaveHeapProfile(ctx, parsed.(*ProfileParams))
	case string(MethodGetReferencesToSymbolInFile):
		return s.handleGetReferencesToSymbolInFile(ctx, parsed.(*GetReferencesToSymbolInFileParams))
	case string(MethodGetReferencedSymbolsForNode):
		return s.handleGetReferencedSymbolsForNode(ctx, parsed.(*GetReferencedSymbolsForNodeParams))
	case string(MethodGetSignatureUsages):
		return s.handleGetSignatureUsages(ctx, parsed.(*GetSignatureUsagesParams))
	case string(MethodGetCompletionsAtPosition):
		return s.handleGetCompletionsAtPosition(ctx, parsed.(*GetCompletionsAtPositionParams))
	default:
		return nil, fmt.Errorf("unknown method: %s", method)
	}
}

func (s *Session) handleStartCPUProfile(_ context.Context, params *ProfileParams) (any, error) {
	if params == nil || params.Dir == "" {
		return nil, fmt.Errorf("%w: dir is required", ErrClientError)
	}
	if err := s.cpuProfiler.StartCPUProfile(params.Dir); err != nil {
		return nil, fmt.Errorf("%w: failed to start CPU profile: %w", ErrClientError, err)
	}
	return nil, nil
}

func (s *Session) handleStopCPUProfile(_ context.Context) (*ProfileResult, error) {
	filePath, err := s.cpuProfiler.StopCPUProfile()
	if err != nil {
		return nil, fmt.Errorf("%w: failed to stop CPU profile: %w", ErrClientError, err)
	}

View on GitHub (pinned to 1bcfa18d79)

Solutions

  1. Use the exported Method constants (api.MethodGetCompletionsAtPosition etc.) instead of string literals
  2. Check whether the server build actually contains the method (grep proto.go unmarshalers for the version you deploy)
  3. Upgrade the older side so client and server agree on the protocol

Example fix

// before
resp, err := conn.Call(ctx, "getCompletionsAtPositin", params)

// after
resp, err := conn.Call(ctx, string(api.MethodGetCompletionsAtPosition), params)
Defensive patterns

Strategy: type-guard

Type guard

func isKnownMethod(m string) bool {
    switch api.Method(m) {
    case api.MethodRelease, api.MethodInitialize, api.MethodUpdateSnapshot,
        api.MethodUpdateTemporarySnapshot, api.MethodParseCommandLine,
        api.MethodReadConfigFile, api.MethodParseJsonConfigFile,
        api.MethodParseConfigFile, api.MethodTranspileModule,
        api.MethodGetCompletionsAtPosition /* ... extend from proto.go */:
        return true
    }
    return false
}

Try / catch

if err != nil && strings.HasPrefix(err.Error(), "unknown method:") {
    // typo or version skew: check the method name against api.Method constants
}

Prevention

When it happens

Trigger: Typo in the method name ("getSymbolAtPositin"); calling a method that only exists in a newer typescript-go than the server binary; sending connection-level methods (getServerTiming, resetServerTiming) directly to the session handler.

Common situations: Client and server built from different versions of the repo so the method list diverges; string literals for method names drifting from the Method* constants during refactors; copy-paste from older protocol docs.

Related errors


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