microsoft/typescript-go · critical · Error

Expected fixed 3-element array (0x93), received: 0x${marker.

Error message

Expected fixed 3-element array (0x93), received: 0x${marker.toString(16)}

What it means

The first byte of an expected [type, name, payload] tuple is not the MessagePack fixarray-3 marker (0x93). The parent and child have lost byte-stream alignment, so the channel can no longer parse frames.

Source

Thrown at _packages/native-preview/src/api/syncChannel.ts:446

                else {
                    this.writeAllBuf(payload as Buffer | Uint8Array);
                }
            }
        }
    }

    // ── MessagePack tuple read ──────────────────────────────────────

    /**
     * Read a [type, name, payload] tuple into instance fields
     * (_msgType, _msgName, _msgPayload) to avoid allocating a
     * short-lived 3-element array on every call.
     */
    private readTuple(): void {
        // Fixed 3-element array marker
        const marker = this.readByte();
        if (marker !== MSGPACK_FIXARRAY3) {
            throw new Error(
                `Expected fixed 3-element array (0x93), received: 0x${marker.toString(16)}`,
            );
        }

        // Message type – positive fixint or uint8
        const tb = this.readByte();
        if (tb <= 0x7f) {
            this._msgType = tb;
        }
        else if (tb === MSGPACK_UINT8) {
            this._msgType = this.readByte();
        }
        else {
            throw new Error(
                `Expected positive fixint or uint8 marker, received: 0x${tb.toString(16)}`,
            );
        }

View on GitHub (pinned to 1bcfa18d79)

Solutions

  1. Ensure the child writes NOTHING to stdout except protocol frames (send logs to stderr)
  2. Restart the session — the channel cannot resynchronize; catch the error, kill the child, and respawn
  3. Rebuild/reinstall so host and child run the same protocol version
  4. If you maintain the child, run its output through the same MessagePack writer on every write path

Example fix

// before (Go child)
fmt.Println("debug info") // corrupts the stdout frame stream

// after
fmt.Fprintln(os.Stderr, "debug info")
Defensive patterns

Strategy: fallback

Try / catch

try { channel.readResponse(); } catch (e) { if (e.message.includes('0x93')) { /* stream corrupted: kill child, spawn fresh session, retry request once */ } throw e; }

Prevention

When it happens

Trigger: Anything corrupting or shifting the child's stdout: stray writes from the child (fmt.Println/debug prints on stdout instead of stderr), interleaved output from grandchild processes, a truncated message from a crashed child, or a partial read followed by a misaligned resume.

Common situations: Building a custom Go child and accidentally printing logs to stdout; piping the child through a tool that mangles bytes; version/protocol drift changing the frame layout; reading the channel after the child died mid-write.

Related errors


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