microsoft/typescript-go · error · Error

${vendorJsonrpcSrc} is not installed; run `npm ci` first.

Error message

${vendorJsonrpcSrc} is not installed; run `npm ci` first.

What it means

During StopTracing, after all per-checker type dumps succeed, the remaining buffered events plus the closing ']\n' are appended to the trace file via fs.AppendFile. Failure here means the trace JSON array was never closed, so the file on disk is syntactically incomplete and will not load in chrome://tracing or perfetto. Note the ordering: a previously recorded flushErr is returned instead (earlier branch), so this specific error only fires when the final append itself fails.

Source

Thrown at Herebyfile.mjs:588

    name: "generate:ast",
    description: "Generates AST and encoder files from ast.json.",
    run: () => $`node --experimental-strip-types --no-warnings ./_scripts/generate.ts`,
});

// ── Vendored npm dependencies ───────────────────────────────────

const vendorJsonrpcDir = "_packages/native-preview/vendor/vscode-jsonrpc";
const vendorJsonrpcSrc = "node_modules/vscode-jsonrpc";
// Files copied verbatim from the installed vscode-jsonrpc package into the
// vendored copy. Only the runtime files needed by the `#vscode-jsonrpc/node`
// import (lib + typings + package.json) plus license/readme are vendored.
const vendorJsonrpcFiles = ["package.json", "README.md", "License.txt", "lib", "typings"];

async function runGenerateVendor() {
    const src = path.join(__dirname, vendorJsonrpcSrc);
    const dest = path.join(__dirname, vendorJsonrpcDir);
    if (!fs.existsSync(src)) {
        throw new Error(`${vendorJsonrpcSrc} is not installed; run \`npm ci\` first.`);
    }
    await rimraf(dest);
    await fs.promises.mkdir(dest, { recursive: true });
    for (const file of vendorJsonrpcFiles) {
        await cpRecursive(path.join(src, file), path.join(dest, file));
    }
}

export const generateVendor = task({
    name: "generate:vendor",
    description: "Updates the vendored copy of vscode-jsonrpc from node_modules.",
    run: runGenerateVendor,
});

const coverageDir = path.join(__dirname, "coverage");

const ensureCoverageDirExists = memoize(() => {
    if (options.coverage) {

View on GitHub (pinned to 1bcfa18d79)

Solutions

  1. Verify disk space and directory permissions at traceDir, then re-run the traced operation — the current file lacks the closing bracket and is unusable.
  2. Confirm the trace file still exists and is appendable by the same user throughout the session (no external truncation).
  3. Validate finished traces before analysis: a quick check that the file ends with ']\n' catches this class of corruption.
  4. Use a local, writable filesystem for traceDir rather than network mounts.

Example fix

// before
_ = tr.StopTracing() // error ignored, broken trace.json

// after
if err := tr.StopTracing(); err != nil {
	return fmt.Errorf("trace session failed (output may be incomplete): %w", err)
}
Defensive patterns

Strategy: try-catch

Try / catch

if err := tr.StopTracing(); err != nil {
	if strings.Contains(err.Error(), "failed to write trace file") {
		log.Printf("trace JSON not finalized (missing closing bracket): %v", err)
	}
	return err // or degrade: continue without trace analysis
}

Prevention

When it happens

Trigger: StopTracing on a session whose final append fails: disk full at close time, trace file removed or made read-only during the run, FS errors on append, or a custom vfs.FS whose AppendFile cannot extend the file. Small sessions that never crossed flushThreshold write their entire content here, so even short runs can hit it.

Common situations: Disk quota exhausted exactly at teardown; trace directory cleaned up by a concurrent job before the process exits; NFS/network filesystem append failures; permissions changed mid-run.

Related errors


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