jdx/mise · error

Main loop reached loop limit (%d). Consider either increasin

Error message

Main loop reached loop limit (%d). Consider either increasing it or checking HTML-code for syntax errors

What it means

htmlparser.lua's main parsing loop (`MainLoop`) guards against infinite loops by counting parsed nodes against `limit`. When the node index reaches the limit, it reports "Main loop reached loop limit (%d)" and breaks, returning a partial tree rather than hanging forever — usually meaning malformed/pathological HTML.

Source

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

				"("..
				(tpr["<"] or "__FAILED__").. -- Here we search for "<", we escaped in previous gsub (and don't break things if we have no escaping replacement)
				")("..
				(opts.tpl_marker_pattern or "[^%w%s]").. -- Capture templating symbol
				")([%g%s]-)".. -- match placeholder's content
				"(%2)(>)".. -- placeholder's tail
				"([^>]*>)", -- remaining
				function(...)return g(5,...)end
			)
		-- }}}
	end -- }}}

	local index = 0
	local root = ElementNode:new(index, str(text))
	local node, descend, tpos, opentags = root, true, 1, {}

	while true do -- MainLoop {{{
		if index == limit then -- {{{
			err("Main loop reached loop limit (%d). Consider either increasing it or checking HTML-code for syntax errors", limit)
			break
		end -- }}}
		-- openstart/tpos Definitions {{{
		local openstart, name
		openstart, tpos, name = root._text:find(
			"<" ..        -- an uncaptured starting "<"
			"([%w-]+)" .. -- name = the first word, directly following the "<"
			"[^>]*>",     -- include, but not capture everything up to the next ">"
		tpos)
		dbg("[MainLoop]:#LINE# openstart=%s || tpos=%s || name=%s",str(openstart),str(tpos),str(name))
		-- }}}
		if not name then break end
		-- Some more vars {{{
		index = index + 1
		local tag = ElementNode:new(index, str(name), (node or {}), descend, openstart, tpos)
		node = tag
		local tagloop
		local tagst, apos = tag:gettext(), 1

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Check the input HTML for syntax errors (unclosed tags, truncation) and fix or fetch it again.
  2. Increase the loop `limit` argument when legitimately parsing very large documents.
  3. Pre-validate the payload (content-type/size checks) before parsing.
  4. Truncate or chunk the document if it is simply too big.

Example fix

// before
local root = htmlparser.parse(bigHtml)  -- default limit hit
// after
local root = htmlparser.parse(bigHtml, nil, 50000)  -- raise loop limit
Defensive patterns

Strategy: validation

Validate before calling

-- bail early on implausibly large or truncated input before parsing
if #html > MAX_INPUT or not html:find("<") then return nil, "input too large or not HTML" end

Type guard

local function looks_truncated(s) return type(s) == "string" and (s:find("<") and not s:find(">")) end

Prevention

When it happens

Trigger: Calling the htmlparser parse function on input where the main loop keeps finding nodes until the configured limit is hit — deeply nested, malformed, truncated, or extremely large documents.

Common situations: vfox plugins parsing huge or broken HTML responses; truncated HTML from failed downloads; minified markup that never terminates cleanly.

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/d85594acb497509c. Report an issue: GitHub.