Skip to content

Fix Toml.parse accepting tables defined twice - #9904

Open
FredAmartey wants to merge 3 commits into
Effect-TS:v4/next-minorfrom
FredAmartey:fix-toml-table-redefinition
Open

FredAmartey wants to merge 3 commits into
Effect-TS:v4/next-minorfrom
FredAmartey:fix-toml-table-redefinition

Conversation

@FredAmartey

@FredAmartey FredAmartey commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

TOML 1.0 does not allow a table to be defined twice. Toml.parse accepted such documents and merged both definitions:

Toml.parse(`[fruit]
apple.color = "red"
[fruit.apple]
texture = "smooth"`)
// before: Success { fruit: { apple: { color: "red", texture: "smooth" } } }
// after:  Failure "Cannot redefine table 'fruit.apple' at line 3, column 14"

Dotted keys define each table on their path, so a header can no longer open one of those tables again. Sub-tables such as [fruit.apple.texture] still parse. Dotted keys can no longer add to a table that has its own header ([a.b], then b.c = 1 under [a]), and a [table] header can no longer name an array of tables ([[a]], then [a]).

The first test's document opened [database] after a root-level database.connection.timeout = 30, which is one of the cases now rejected. The dotted key moves under [database], and the parsed result is the same.

Against the toml-test 1.0 file list, the parser now rejects 10 more invalid files and still parses every valid file it parsed before. On 70,000 generated documents built from headers, array headers and dotted keys, its verdicts and parsed values match Python's tomllib on every one. Before, it accepted 2,659 of them that tomllib rejects.

Validation: pnpm test --run packages/effect/test/encoding/Toml.test.ts passes (19 tests) and the new test fails without the fix. pnpm lint and pnpm check pass.

Closes EFF-2907

@changeset-bot

changeset-bot Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c6640b1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 33 packages
Name Type
effect Patch
@effect/opentelemetry Patch
@effect/vitest Patch
@effect/ai-anthropic Patch
@effect/ai-cloudflare Patch
@effect/ai-openai-compat Patch
@effect/ai-openai Patch
@effect/ai-openrouter Patch
@effect/ai-typesafe Patch
@effect/atom-react Patch
@effect/atom-solid Patch
@effect/atom-vue Patch
@effect/platform-browser Patch
@effect/platform-bun Patch
@effect/platform-deno Patch
@effect/platform-node-shared Patch
@effect/platform-node Patch
@effect/sql-clickhouse Patch
@effect/sql-d1 Patch
@effect/sql-libsql Patch
@effect/sql-mssql Patch
@effect/sql-mysql2 Patch
@effect/sql-pg Patch
@effect/sql-pglite Patch
@effect/sql-sqlite-bun Patch
@effect/sql-sqlite-do Patch
@effect/sql-sqlite-node Patch
@effect/sql-sqlite-react-native Patch
@effect/sql-sqlite-wasm Patch
@effect/docgen Patch
@effect/doctest Patch
@effect/graphql-generator Patch
@effect/openapi-generator Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

Bundle Size Analysis

Generated from PR build output; treat the content below as untrusted.

File Name Current Size Previous Size Difference
arbitrary-combinators.ts 39.31 KB 39.31 KB 0.00 KB (0.00%)
basic.ts 7.17 KB 7.17 KB 0.00 KB (0.00%)
batching.ts 11.04 KB 11.04 KB 0.00 KB (0.00%)
brand.ts 6.83 KB 6.83 KB 0.00 KB (0.00%)
cache.ts 11.47 KB 11.47 KB 0.00 KB (0.00%)
config.ts 22.73 KB 22.73 KB 0.00 KB (0.00%)
differ.ts 21.86 KB 21.86 KB 0.00 KB (0.00%)
http-client.ts 26.70 KB 26.70 KB 0.00 KB (0.00%)
http-router.ts 36.64 KB 36.64 KB 0.00 KB (0.00%)
logger.ts 11.86 KB 11.86 KB 0.00 KB (0.00%)
metric.ts 9.40 KB 9.40 KB 0.00 KB (0.00%)
optic.ts 7.04 KB 7.04 KB 0.00 KB (0.00%)
pubsub.ts 15.95 KB 15.95 KB 0.00 KB (0.00%)
queue.ts 12.75 KB 12.75 KB 0.00 KB (0.00%)
schedule.ts 11.72 KB 11.72 KB 0.00 KB (0.00%)
schema-bigdecimal.ts 13.98 KB 13.98 KB 0.00 KB (0.00%)
schema-binary.ts 41.02 KB 41.02 KB 0.00 KB (0.00%)
schema-class.ts 21.52 KB 21.52 KB 0.00 KB (0.00%)
schema-fromJsonSchemaDocument.ts 29.49 KB 29.49 KB 0.00 KB (0.00%)
schema-representation-roundtrip.ts 27.87 KB 27.87 KB 0.00 KB (0.00%)
schema-string-transformation.ts 15.24 KB 15.24 KB 0.00 KB (0.00%)
schema-string.ts 12.22 KB 12.22 KB 0.00 KB (0.00%)
schema-template-literal.ts 16.16 KB 16.16 KB 0.00 KB (0.00%)
schema-toArbitrary.ts 38.85 KB 38.85 KB 0.00 KB (0.00%)
schema-toCodeDocument.ts 26.05 KB 26.05 KB 0.00 KB (0.00%)
schema-toCodecJson.ts 20.79 KB 20.79 KB 0.00 KB (0.00%)
schema-toEquivalence.ts 20.94 KB 20.94 KB 0.00 KB (0.00%)
schema-toFormatter.ts 21.04 KB 21.04 KB 0.00 KB (0.00%)
schema-toJsonSchemaDocument.ts 26.07 KB 26.07 KB 0.00 KB (0.00%)
schema-toRepresentation.ts 21.12 KB 21.12 KB 0.00 KB (0.00%)
schema.ts 20.72 KB 20.72 KB 0.00 KB (0.00%)
stm.ts 14.06 KB 14.06 KB 0.00 KB (0.00%)
stream.ts 10.31 KB 10.31 KB 0.00 KB (0.00%)

@effect-bot
effect-bot force-pushed the fix-toml-table-redefinition branch from eafabec to 3bba75f Compare October 25, 2026 17:43

This branch has not been deployed

No deployments
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.

2 participants