{"record":{"id":"7eb248577d315933","repo":"garrytan/gstack","slug":"viewport-scale-value-must-be-a-finite-number-g","errorCode":null,"errorMessage":"viewport --scale: value must be a finite number, got ${scale}","messagePattern":"viewport --scale: value must be a finite number, got (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"browse/src/browser-manager.ts","lineNumber":1482,"sourceCode":"      }\n      return `Context recreation failed: ${err instanceof Error ? err.message : String(err)}. Browser reset to blank tab.`;\n    }\n  }\n\n  /**\n   * Change deviceScaleFactor + viewport size atomically.\n   *\n   * deviceScaleFactor is a context-level option, so Playwright requires a full context\n   * recreation. This method validates the input, stores the new values, calls\n   * recreateContext(), and rolls back the fields on failure so a bad call doesn't\n   * leave the manager in an inconsistent state.\n   *\n   * Returns null on success, or an error string if the new context couldn't be built\n   * (state may have been lost, per recreateContext's fallback behavior).\n   */\n  async setDeviceScaleFactor(scale: number, width: number, height: number): Promise<string | null> {\n    if (!Number.isFinite(scale)) {\n      throw new Error(`viewport --scale: value must be a finite number, got ${scale}`);\n    }\n    if (scale < 1 || scale > 3) {\n      throw new Error(`viewport --scale: value must be between 1 and 3 (gstack policy cap), got ${scale}`);\n    }\n    if (this.connectionMode === 'headed') {\n      throw new Error('viewport --scale is not supported in headed mode — scale is controlled by the real browser window.');\n    }\n\n    const prevScale = this.deviceScaleFactor;\n    const prevViewport = { ...this.currentViewport };\n    this.deviceScaleFactor = scale;\n    this.currentViewport = { width, height };\n\n    const err = await this.recreateContext();\n    if (err !== null) {\n      // recreateContext's fallback path built a blank context using the NEW scale +\n      // viewport (the fields we just set). Rolling the fields back without a second\n      // recreate would leave the live context at new-scale while state says old-scale.","sourceCodeStart":1464,"sourceCodeEnd":1500,"githubUrl":"https://github.com/garrytan/gstack/blob/94993f74012782fd94416dd44b8314f6363a13a4/browse/src/browser-manager.ts#L1464-L1500","documentation":"Error \"viewport --scale: value must be a finite number, got ${scale}\" thrown in garrytan/gstack.","triggerScenarios":"Thrown at browse/src/browser-manager.ts:1482 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"94993f74012782fd94416dd44b8314f6363a13a4","analyzedAt":"2026-08-12T04:06:23.140Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}