rclone/rclone · error · Error

total length of command line and environment variables excee

Error message

total length of command line and environment variables exceeds limit

What it means

Before starting the Go program, wasm_exec.js copies argv strings and environment variables into the WASM linear memory starting at address 0. The Go linker guarantees real global data begins at wasmMinDataAddr = 4096 + 8192 = 12288 bytes; if the argv/env block would reach that address it would overwrite global data, so run() aborts with this error instead of corrupting memory.

Source

Thrown at fs/rc/js/wasm_exec.js:627

      const keys = Object.keys(this.env).sort();
      keys.forEach((key) => {
        argvPtrs.push(strPtr(`${key}=${this.env[key]}`));
      });
      argvPtrs.push(0);

      const argv = offset;
      argvPtrs.forEach((ptr) => {
        this.mem.setUint32(offset, ptr, true);
        this.mem.setUint32(offset + 4, 0, true);
        offset += 8;
      });

      // The linker guarantees global data starts from at least wasmMinDataAddr.
      // Keep in sync with cmd/link/internal/ld/data.go:wasmMinDataAddr.
      const wasmMinDataAddr = 4096 + 8192;
      if (offset >= wasmMinDataAddr) {
        throw new Error(
          "total length of command line and environment variables exceeds limit",
        );
      }

      this._inst.exports.run(argc, argv);
      if (this.exited) {
        this._resolveExitPromise();
      }
      await this._exitPromise;
    }

    _resume() {
      if (this.exited) {
        throw new Error("Go program has already exited");
      }
      this._inst.exports.resume();
      if (this.exited) {
        this._resolveExitPromise();

View on GitHub (pinned to f0b210a886)

Solutions

  1. Trim go.env to only the variables the Go program needs instead of copying process.env wholesale
  2. Shorten or remove oversized argv entries and env values (drop base64 blobs, certs, tokens from env if unused)
  3. If genuinely more space is needed, rebuild the Go WASM module with a linker flag raising the data start (see cmd/link -W gclicated // in practice: raise wasmMinDataAddr in both the toolchain and this file consistently) - last resort, requires keeping wasmMinDataAddr in sync with cmd/link/internal/ld/data.go

Example fix

// before
go.env = process.env; // hundreds of vars, incl. huge CI secrets
await go.run(instance); // throws: exceeds limit

// after
go.env = { PATH: process.env.PATH, HOME: process.env.HOME };
await go.run(instance);
Defensive patterns

Strategy: validation

Validate before calling

// Before go.run(instance): rough budget check (limit is 12288 bytes of argv+env)
const encoded = (s) => s.length + 1 + 8 /* ptr slot */ + 4 /* size field */;
const total = go.argv.reduce((n, s) => n + encoded(s), 0) +
              Object.entries(go.env).reduce((n, [k, v]) => n + encoded(k + '=' + v), 0);
if (total >= 12288) throw new Error(`argv/env too large: ${total} >= 12288 bytes`);

Try / catch

try { await go.run(instance); } catch (e) { if (/command line and environment/.test(e.message)) { go.env = pickNeededVars(go.env); /* retry with trimmed env */ } else throw e; }

Prevention

When it happens

Trigger: Passing a Go instance with a very large go.argv array (this.argv = ["js"] by default), a huge go.env dictionary, or a combination whose encoded bytes (each string + NUL + 4-byte length + pointer table) total >= 12288 bytes. Each entry costs roughly len(string)+1 plus 8 bytes of pointer slot plus a 4-byte size field.

Common situations: Forwarding an entire process environment into go.env (e.g. go.env = process.env when the CI/secret-laden environment is enormous), passing long argument lists, or base64/huge tokens in env vars. Rare in normal use; appears in wrapper harnesses that bulk-copy environments.

Related errors


AI-assisted analysis of rclone/rclone@f0b210a886 (2026-08-15). Data as JSON: /api/errors/3386859d7c371f74. Report an issue: GitHub.