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
- Only call getNodeId on nodes returned by decodeNode() or by the native API itself
- If you fabricated the node, track its identity yourself instead of relying on getNodeId
- 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
- Only pass nodes from decodeNode() or API returns into getNodeId
- Keep a single copy of @typescript/native-preview installed so instanceof checks hold
- Track identity for nodes you construct yourself instead of using getNodeId
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
- Invalid node handle: ${handle}
- Invalid value for ${name}: ${value}
- Found external imports in .d.ts files:\n${importErrors.map(e
- Expected ${pkgName} to declare exactly one bin entry named $
- Unable to resolve ${platformPackageName}. Either your platfo
AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16).
Data as JSON: /api/errors/aeb04f2b8f85c18f.
Report an issue: GitHub.