garrytan/gstack · error · Error

load-html: ${absolutePath} has ${ext} extension but content

Error message

load-html: ${absolutePath} has ${ext} extension but content does not look like HTML. First bytes: ${hexDump}

What it means

Error "load-html: ${absolutePath} has ${ext} extension but content does not look like HTML. First bytes: ${hexDump}" thrown in garrytan/gstack.

Source

Thrown at browse/src/write-commands.ts:315

      // Single read: Buffer → magic-byte peek → utf-8 string
      const buf = await fs.promises.readFile(absolutePath);

      // Magic-byte check: strip UTF-8 BOM + leading whitespace, then verify the first
      // non-whitespace byte starts a markup construct. Accepts any <tag, <!doctype,
      // <!-- comment, <?xml prolog — including bare HTML fragments like `<div>...</div>`
      // which setContent wraps in a full document. Rejects binary files mis-renamed .html
      // (first byte won't be `<`).
      let peek = buf.slice(0, 200);
      if (peek[0] === 0xEF && peek[1] === 0xBB && peek[2] === 0xBF) {
        peek = peek.slice(3);
      }
      const peekStr = peek.toString('utf8').trimStart();
      // Valid markup opener: '<' followed by alpha (tag), '!' (doctype/comment), or '?' (xml prolog)
      const looksLikeMarkup = /^<[a-zA-Z!?]/.test(peekStr);
      if (!looksLikeMarkup) {
        const hexDump = Array.from(buf.slice(0, 16)).map(b => b.toString(16).padStart(2, '0')).join(' ');
        throw new Error(
          `load-html: ${absolutePath} has ${ext} extension but content does not look like HTML. First bytes: ${hexDump}`
        );
      }

      const html = buf.toString('utf8');
      await session.setTabContent(html, { waitUntil });
      return `Loaded HTML: ${absolutePath} (${stat.size} bytes)`;
    }

    case 'click': {
      const selector = args[0];
      if (!selector) throw new Error('Usage: browse click <selector>');

      // Auto-route: if ref points to a real <option> inside a <select>, use selectOption
      const role = session.getRefRole(selector);
      if (role === 'option') {
        const resolved = await session.resolveRef(selector);
        if ('locator' in resolved) {

View on GitHub (pinned to 94993f7401)

When it happens

Trigger: Thrown at browse/src/write-commands.ts:315 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12). Data as JSON: /api/errors/1e72e4229363bf41. Report an issue: GitHub.