Skip to content

fix(core): webfetch HTML→Markdown renumbers hex-spelled ordered lists — bare parseInt reads start="0x10" as item 16 instead of 0 #743

Closed

Description

@dezren39

Problem

The HTML→Markdown converter used by webfetch reads an ordered list's start and an item's value with a bare Number.parseInt(...) (no radix). parseInt auto-detects a 0x prefix as hexadecimal, so a hex-spelled attribute is reinterpreted as a hex number — while HTML's own integer parsing (optional sign, then ASCII digits only, stop at the first non-digit) reads the same attribute as 0. The converted markdown silently renumbers the list.

Evidence (verified this run, 2026-10-28)

  • packages/core/src/tool/html-markdown.ts:403 — const start = Number.parseInt(attributes.start ?? "1") (no radix argument).
  • packages/core/src/tool/html-markdown.ts:411 — const value = Number.parseInt(attributes.value ?? "") (no radix argument).
  • Laptop probe (probe dir ~/git/fleet/probe-2026-10-28-htmlmd/ on the laptop; imports the real convertHTMLToMarkdown from the laptop clone, whose html-markdown.ts sha256 49333c55… is byte-identical to sandbox main b0633cc697; run with bun from packages/core):
    • control <ol start="3"> → "3. a\n\n4. b" ✓
    • <ol start="0x10"> → "16. a\n\n17. b" — HTML parsing reads 0x10 as 0, so a browser renders this list starting at 0
    • <ol start="-0x10"> → "-16. a\n\n-15. b" — HTML parsing reads it as 0 (-0)
    • <ol><li value="0x20"> → "32. a\n\n33. b" — HTML parsing reads 0x20 as 0
    • controls that agree either way: start="1e2" → 1, start="08" → 8
  • The converter is the webfetch path: packages/core/src/tool/plugin/webfetch.ts:9 imports convertHTMLToMarkdown from this module, so fetched pages reach the model with the renumbered lists.
  • Dedup: searched open/closed issues for parseInt, "ordered list", htmlparser on 2026-10-28 — fix(tui): editor SSE and IDE lock-file ports parsed with bare parseInt — malformed values silently connect to the wrong port #246 covers TUI editor/IDE ports parsed with parseInt, a different surface; nothing covers html-markdown list numbering.

Why it matters

Webfetch output is ground truth the model reasons from. A page whose list is numbered from 0 (or whose items carry explicit values) comes back numbered from 16/32 instead, with no error anywhere — cross-references in the page text ("see step 16") then point at the wrong items, and quoted numbering is silently corrupted.

Acceptance criteria

  • start/value attributes are parsed with HTML integer grammar (optional sign + decimal digits; trailing non-digits ignored the way the HTML parser ignores them), never radix auto-detection: 0x10 → 0, -0x10 → 0, 0x20 → 0.
  • Ordinary values are unchanged: start="3" → 3, start="08" → 8, start="1e2" → 1, negative decimal starts keep working, and a missing/unparseable start still defaults to 1 while an unparseable value still leaves the counter untouched.
  • New tests in the html-markdown test set pin the hex-spelled start and value cases plus the decimal controls.
  • No change to unordered lists, nested-list counters, or the markdown byte budget behaviour.

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    task/small-fixQueue packet kind: bounded fix with reproduction and targeted tests
    source/creatorFiled by the new-issue-creator job
    priority/lowNice to have; do when convenient
    queue/queuedHas a queued task in the Supabase agent queue
    app/corePackage: core (pkgs/ or apps/ in this repo)
    effort/xsTrivial: expected under 30 minutes of work
    on Oct 28, 2026
  2. dezren39 commented on Oct 28, 2026

    @dezren39
    Author

    🤖 Agent note · filed

    • Agent: new-issue-creator job (new-issue-creator-opencode)
    • Session / ID: cron new-issue-creator-opencode run 2026-10-28 13:35 CDT
    • Found via: filed this run
    • Task: Filed after verifying on main b0633cc697 that packages/core/src/tool/html-markdown.ts:403,411 parse ol start / li value with bare Number.parseInt (no radix), so 0x-spelled attributes are read as hexadecimal while HTML integer parsing reads them as 0. Laptop probe of the real convertHTMLToMarkdown (module sha256 identical to main): start="0x10" → items 16/17, start="-0x10" → -16/-15, value="0x20" → 32/33; controls start="3", "08", "1e2" correct.
    • Expectation: effort/xs — small-fix: parse both attributes with the HTML integer grammar (sign + decimal digits), pin hex-spelled and decimal cases in the html-markdown tests; defaults (missing start → 1, unparseable value → counter untouched) unchanged.
    • Links: queue packet packet-743.json (repo-health-opencode-pilot, small_fix); probe ~/git/fleet/probe-2026-10-28-htmlmd/ (laptop); evidence body hidden_files/issue-opencode-htmlmd-list-hex-body.md
  3. developing-today commented on Oct 28, 2026

    @developing-today
  4. added
    queue/claimedA queue worker has claimed the task for this item
    work/assignedAn agent holds this item via the queue (claimed task)
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 28, 2026
  5. dezren39 commented on Oct 28, 2026

    @dezren39
    Author

    🤖 Agent note · parked on CI

  6. added
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    status/parkedDeliberately paused with a recorded resume condition
    and removed
    queue/claimedA queue worker has claimed the task for this item
    on Oct 28, 2026
  7. removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    work/assignedAn agent holds this item via the queue (claimed task)
    on Oct 28, 2026
  8. dezren39 commented on Oct 28, 2026

    @dezren39
    Author

    🤖 Agent note · merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    app/corePackage: core (pkgs/ or apps/ in this repo)effort/xsTrivial: expected under 30 minutes of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/lowNice to have; do when convenientsource/creatorFiled by the new-issue-creator jobstatus:donetask/small-fixQueue packet kind: bounded fix with reproduction and targeted tests

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions