mozilla/pdf.js · error · Error

app.fs is read-only

Error message

app.fs is read-only

What it means

app.fs is a lazily-created Proxy around a FullScreen helper used to drive fullscreen UI via the external send callback. Because it is viewer-internal state, PDF.js exposes it read-only and the setter throws. Assigning would sever the proxy wiring to the host viewer.

Source

Thrown at src/scripting_api/app.js:249

  }

  get fromPDFConverters() {
    return [];
  }

  set fromPDFConverters(_) {
    throw new Error("app.fromPDFConverters is read-only");
  }

  get fs() {
    return (this._fs ??= new Proxy(
      new FullScreen({ send: this._send }),
      this._proxyHandler
    ));
  }

  set fs(_) {
    throw new Error("app.fs is read-only");
  }

  get language() {
    return this._language;
  }

  set language(_) {
    throw new Error("app.language is read-only");
  }

  get media() {
    return undefined;
  }

  set media(_) {
    throw new Error("app.media is read-only");
  }

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Use the returned FullScreen proxy's own methods/properties instead of reassigning app.fs.
  2. Keep any test mocks at the underlying send/_externalCall layer, not by overwriting app.fs.
  3. Read app.fs.* (e.g. transitions, click) for fullscreen control.

Example fix

// before
app.fs = myFullScreen;
// after
app.fs.click = false; // mutate properties, never reassign
Defensive patterns

Strategy: validation

Validate before calling

// app.fs is a viewer-managed FullScreen proxy; read/use, never reassign.
function withFullScreen(app, fn) {
  const fs = app.fs;
  if (!fs || typeof fs !== 'object') throw new Error('FullScreen unavailable');
  return fn(fs);
}

Type guard

const isFullScreenProxy = (v) =>
  v != null && typeof v === 'object' && typeof v.constructor?.name === 'string';

Try / catch

try { /* code that may assign app.fs */ }
catch (e) { if (!/fs is read-only/.test(e.message)) throw e; }

Prevention

When it happens

Trigger: Any assignment app.fs = ... in PDF JavaScript or API test code hits the throw at src/scripting_api/app.js:249.

Common situations: Scripts attempting to replace the fullscreen object with a mock; authors thinking fs is a configurable file-system handle (it is not).

Related errors


AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13). Data as JSON: /api/errors/988e7f2ae131ca1a. Report an issue: GitHub.