Skip to content

fix: keep other table array entries' sub-tables when removing one entry - #321

Merged
DecimalTurn merged 4 commits into
DecimalTurn:latestfrom
Rethunk-AI:fix/aot-entry-subtables
Oct 17, 2026
Merged

DecimalTurn merged 4 commits into
DecimalTurn:latestfrom
Rethunk-AI:fix/aot-entry-subtables

Conversation

@AlbinoGeek

Copy link
Copy Markdown
Contributor

Problem

Removing one entry from an array of tables deletes the sub-tables of every other entry too.

import { parse, patch } from '@decimalturn/toml-patch'

const src = `[[route]]
id = "a"
[route.args]
x = 1

[[route]]
id = "b"
[route.args]
y = 2
`
const updated = parse(src)
updated.route.splice(1, 1)
console.log(patch(src, updated))

On 3.3.0 and on latest (b092c65) this prints:

[[route]]
id = "a"

route[0].args is gone. diff() is correct here: it emits one Remove ["route", 1].

Cause

In src/patch.ts, the "Same repair for a removed SECTION header" block (added for fuzz seed 136292) removes every document-level sibling whose key extends the removed header's key. That is right for a [table]. A [[table]] entry, though, only owns the [route.args] sections between its own header and the next [[route]] header, and the sweep was also catching the other entries' sections.

Fix

For a TableArray node, the sweep now only looks at siblings between the entry and the next [[...]] header with the same key. The behaviour for [table] headers is unchanged.

Tests

  • New test in src/__tests__/patch.test.ts: removes each of three [[route]] entries that all have [route.args], and checks that parse(patch(...)) equals the updated object. It fails before the fix and passes after.
  • pnpm run typecheck, pnpm run lint, pnpm run build, vitest run (63 files, 3412 passed, submodules initialised) and pnpm run test:js (131 passed) all pass locally. I ran them with bun instead of pnpm.
  • Also checked against a 36 KB real-world config (23 [[route]] entries, many with [route.args] and comments): removing one entry now changes only that entry's own lines.

CHANGELOG.md has an entry under Unreleased / Fixed.

🤖 Generated with Claude Code

Copilot AI balanced review requested due to automatic review settings October 17, 2026 16:51
@AlbinoGeek

Copy link
Copy Markdown
Contributor Author

[ It was breaking a LOT of our TOML files, bahaha. ]

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Nested-array removal can still cross an ancestor entry boundary and delete surviving sub-tables.

1 open issue
What changed in this PR

This PR limits sub-table cleanup when removing an array-of-tables entry, preserving sections owned by other entries.

Changes:

  • Bounds cleanup at the next same-key array header.
  • Adds regression coverage for removing each of three entries.
  • Documents the fix in the changelog.
File Description
src/​patch.ts Limits the sibling cleanup range.
src/​__tests__/​patch.test.ts Tests preservation of surviving entries’ sub-tables.
CHANGELOG.md Records the fix under Unreleased.

Review effort: Balanced

Comment thread src/patch.ts Outdated
@DecimalTurn

Copy link
Copy Markdown
Owner

Thanks for this fix! I'm planning to check why this wasn't caught earlier during fuzz testing, but I'll merge this in the meantime, so this specific bug is handled correctly, but I'm guesing there might be some other related ones related to some deletions in complex AOT nesting structures.

@DecimalTurn
DecimalTurn merged commit 40f8a05 into DecimalTurn:latest Oct 17, 2026
35 checks passed
@AlbinoGeek

AlbinoGeek commented Oct 17, 2026 via email

Copy link
Copy Markdown
Contributor Author

@DecimalTurn

Copy link
Copy Markdown
Owner

Woah, 65MB! This is certainly pushing beyond TOML's original purpose of offering human readable config files.
Is there a reason why you chose TOML to store this data?

@AlbinoGeek

AlbinoGeek commented Oct 21, 2026 via email

Copy link
Copy Markdown
Contributor Author

@DecimalTurn

Copy link
Copy Markdown
Owner

Totally agree for YAML. For JSON, the file size compared to TOML would be usually smaller based on what I've read, but this might depend on the level of nesting and the average length of your keys. But if TOML works in your case, why not!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants