microsoft/typescript-go · error

getNodeId requires a RemoteNode

Error message

getNodeId requires a RemoteNode

What it means

getNodeId only accepts a RemoteNode, i.e. a node that was decoded from binary data produced by the native (tsgo) server via decodeNode() or obtained through the native-preview API. Any other Node implementation (a locally constructed AST node, a plain object cast to Node, or a node from a different decoder) lacks the remote id backing store, so the function refuses it. The throw is an intentional type check because Node is a structural interface that cannot distinguish remote nodes statically.

Source

Thrown at _packages/native-preview/src/api/node/node.ts:358

}

/**
 * Decode binary-encoded AST data into a Node.
 * Works for any binary-encoded node, including synthetic nodes
 * (e.g. from typeToTypeNode) that don't have a source file.
 */
export function decodeNode(data: Uint8Array): Node {
    const sf = new RemoteSourceFile(data, new Wtf8Decoder());
    return sf as unknown as Node;
}

/**
 * Get the unique ID string for a remote node.
 * Throws if the node is not a RemoteNode (i.e. not decoded from binary data).
 */
export function getNodeId(node: Node): string {
    if (!(node instanceof RemoteNode)) {
        throw new Error("getNodeId requires a RemoteNode");
    }
    return node.id;
}

View on GitHub (pinned to 1bcfa18d79)

Solutions

  1. Only call getNodeId on nodes returned by decodeNode() or by the native API itself
  2. If you fabricated the node, track its identity yourself instead of relying on getNodeId
  3. Check for duplicate @typescript/native-preview installs (npm ls) if the node really is remote but instanceof fails — two module copies break instanceof

Example fix

// before
const id = getNodeId({ kind: 75 } as Node); // throws

// after
import { decodeNode, getNodeId } from "@typescript/native-preview";
const node = decodeNode(binaryFromServer);
const id = getNodeId(node);
Defensive patterns

Strategy: type-guard

Validate before calling

import { RemoteNode } from "...remote-node-module";
const isRemote = (n: Node): boolean => n instanceof RemoteNode;

Type guard

function isRemoteNode(n: Node): boolean {
  // RemoteNode is the class produced by decodeNode; instanceof is the definitive check
  return typeof (n as { id?: unknown }).id === "string" && n.constructor?.name === "RemoteNode";
}

Try / catch

try { id = getNodeId(node); } catch (e) { if ((e as Error).message.includes("requires a RemoteNode")) { /* fall back to your own node identity */ } else throw e; }

Prevention

When it happens

Trigger: Calling getNodeId(node) where node came from anything other than decodeNode(new Uint8Array(...)) or an API-returned node: e.g. getNodeId({ kind: SyntaxKind.Identifier } as Node), getNodeId on a node built by your own parser, or a node obtained from the old/async wire format that is not a RemoteNode instance.

Common situations: Mixing node objects from different APIs (checker-returned nodes vs locally fabricated stubs), upgrading @typescript/native-preview versions where the RemoteNode class identity changed (two copies of the package loaded), or test code creating fake Node objects.

Related errors


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