jdx/mise · error

Impossible to find at least two unused byte codes in this HT

Error message

Impossible to find at least two unused byte codes in this HTML-code. We need it to escape bracket-contained placeholders inside tags.

What it means

vfox's embedded htmlparser.lua scans bytes 0–255 to find two unused byte codes it can substitute for '<' and '>' while escaping placeholders. If either '<' or '>' has no free replacement code in the parsed HTML, it emits this fatal error: there are no spare byte codes left to perform the escaping.

Source

Thrown at crates/vfox/lua/htmlparser.lua:88

					dbg("%s",str(busy[i]))
				else -- if < or >
					dbg("[FindPH]:#LINE# Done!",i)
					break
				end -- if < or > -- }}}
			else -- text!match(cc)
				dbg("[FindPH]:#LINE# Text contains this byte! || i=%d",i)
			end -- text!match(cc) -- }}}
			local skip=1
			if i==31 then
				skip=96 -- ASCII
			end
			i=i+skip
		until (i==255) -- }}}
		i=nil
		--- }}}

		if not(tpr["<"]) or not(tpr[">"]) then
			err("Impossible to find at least two unused byte codes in this HTML-code. We need it to escape bracket-contained placeholders inside tags.")
			err("Consider enabling 'keep_danger_placeholders' option (to silence this error, if parser wasn't failed with current HTML-code) or manually replace few random bytes, to free up the codes.")
		else
			dbg("[FindPH]:#LINE# Found! || '<'=%d, '>'=%d",tpr["<"]:byte(),tpr[">"]:byte())
		end

--	dbg("tpr[>] || tpr[] || #busy%d")

		-- g {{{
		local function g(id,...)
			local arg={...}
			local orig=arg[id]
			arg[id]=arg[id]:gsub("(.)",tpr)
			if arg[id] ~= orig then
				tpl=true
				dbg("[g]:#LINE# orig: %s", str(orig))
				dbg("[g]:#LINE# replaced: %s",str(arg[id]))
			end
			dbg("[g]:#LINE# called, id: %s, arg[id]: %s, args { "..(("{%s}, "):rep(#arg):gsub(", $","")).." }",id,arg[id],...)

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Enable the 'keep_danger_placeholders' option to silence the error when the parser still succeeds with the current HTML.
  2. Manually replace a few random bytes in the input to free up unused byte codes.
  3. Sanitize/normalize the input before parsing (strip non-text bytes).
  4. Fix the plugin to use a different parsing approach for such payloads.

Example fix

// before
local root = htmlparser.parse(html)
-- errors: no unused byte codes
// after
-- before parsing, free byte codes by replacing exotic bytes
html = html:gsub("[\128-\255]", "")
local root = htmlparser.parse(html)
Defensive patterns

Strategy: validation

Validate before calling

-- Lua: ensure input is text-like before parsing
assert(type(html) == "string" and #html > 0, "non-HTML payload")

Type guard

local function is_html_like(s) return type(s) == "string" and s:find("<") ~= nil end

Prevention

When it happens

Trigger: Parsing HTML content so dense with byte values that both '<' and '>' placeholder mappings cannot find unused codes; occurs inside `FindPH` after the 0..255 scan loop when `tpr["<"]` or `tpr[">"]` is nil.

Common situations: vfox plugin hooks feeding binary-ish or highly encoded content to the Lua HTML parser; pages with nearly all byte values present; plugins using htmlparser on non-HTML payloads.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/a0695b5c25ea0152. Report an issue: GitHub.