Title: sqlite: session[Symbol.dispose]() silently ignores the in-use guard · Issue #65447 · nodejs/node · GitHub
Open Graph Title: sqlite: session[Symbol.dispose]() silently ignores the in-use guard · Issue #65447 · nodejs/node
X Title: sqlite: session[Symbol.dispose]() silently ignores the in-use guard · Issue #65447 · nodejs/node
Description: Version v27.0.0-pre (current main) Platform Linux ari-cachyos 7.1.8-1-cachyos #1 SMP PREEMPT_DYNAMIC Mon, 10 Aug 2026 19:39:40 +0000 x86_64 GNU/Linux Subsystem node:sqlite What steps will reproduce the bug? const { DatabaseSync, constant...
Open Graph Description: Version v27.0.0-pre (current main) Platform Linux ari-cachyos 7.1.8-1-cachyos #1 SMP PREEMPT_DYNAMIC Mon, 10 Aug 2026 19:39:40 +0000 x86_64 GNU/Linux Subsystem node:sqlite What steps will reproduce...
X Description: Version v27.0.0-pre (current main) Platform Linux ari-cachyos 7.1.8-1-cachyos #1 SMP PREEMPT_DYNAMIC Mon, 10 Aug 2026 19:39:40 +0000 x86_64 GNU/Linux Subsystem node:sqlite What steps will reproduce...
Opengraph URL: https://github.com/nodejs/node/issues/65447
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"sqlite: session[Symbol.dispose]() silently ignores the in-use guard","articleBody":"### Version\n\nv27.0.0-pre (current main)\n\n### Platform\n\n```text\nLinux ari-cachyos 7.1.8-1-cachyos #1 SMP PREEMPT_DYNAMIC Mon, 10 Aug 2026 19:39:40 +0000 x86_64 GNU/Linux\n```\n\n### Subsystem\n\nnode:sqlite\n\n### What steps will reproduce the bug?\n\n```js\nconst { DatabaseSync, constants } = require('node:sqlite');\n\nfor (const [name, close] of [\n ['close()', (session) => session.close()],\n ['[Symbol.dispose]()', (session) => session[Symbol.dispose]()],\n]) {\n const db = new DatabaseSync(':memory:');\n db.exec('CREATE TABLE data(key INTEGER PRIMARY KEY, value TEXT)');\n const session = db.createSession({ table: 'data' });\n db.exec(\"INSERT INTO data VALUES (1, 'value')\");\n\n let attempted = false;\n db.setAuthorizer(() => {\n if (!attempted) {\n attempted = true;\n try {\n close(session);\n console.log(`${name}: no throw`);\n } catch (error) {\n console.log(`${name}: ${error.code}: ${error.message}`);\n }\n }\n return constants.SQLITE_OK;\n });\n\n session.changeset();\n db.setAuthorizer(null);\n session.close();\n db.close();\n}\n```\n\n### How often does it reproduce? Is there a required condition?\n\nEvery time disposal is attempted while the session is generating a changeset or patchset.\n\n### What is the expected behavior? Why is that the expected behavior?\n\n`session[Symbol.dispose]()` should throw the same `ERR_INVALID_STATE` as `session.close()` when the session cannot be closed safely. `StatementSync` already follows this pattern: its disposal propagates the active-statement guard, with coverage in `test/parallel/test-sqlite-diagnostic-channel.js` under “subscriber cannot close the database or statement”.\n\nExpected output:\n\n```text\nclose(): ERR_INVALID_STATE: session is currently in use\n[Symbol.dispose](): ERR_INVALID_STATE: session is currently in use\n```\n\n### What do you see instead?\n\n```text\nclose(): ERR_INVALID_STATE: session is currently in use\n[Symbol.dispose](): no throw\n```\n\n`Session::Dispose()` catches and discards the exception from `Session::Close()`. The session remains open even though disposal appeared to succeed.\n\n### Additional information\n\nThe reentrancy guard added by #65349 works: `sqlite3session_delete()` is not called while changeset generation is active, so this does not reproduce the use-after-free that the guard prevents. The remaining bug is the silent no-op and inconsistent error propagation from `[Symbol.dispose]()`.\n","author":{"url":"https://github.com/arimxyer","@type":"Person","name":"arimxyer"},"datePublished":"2026-08-20T22:01:02Z","url":"https://github.com/nodejs/node/issues/65447"}
| react-profiling | 0 |
| react-import-map | react,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@d5750093facf |
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:7b8808ff-fd1a-7574-3b5d-37861b0dc0fa |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | C366:185F51:81A39F:AC4069:6AED2688 |
| html-safe-nonce | 50d5f4638df95706d5599e956881f153639bc4adf3347e8e36c2eda682ee1037 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDMzY2OjE4NUY1MTo4MUEzOUY6QUM0MDY5OjZBRUQyNjg4IiwidmlzaXRvcl9pZCI6IjU5NDgyNDQzMTkwNjIwMDk0ODAiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 4fcf045fc378235d10be850f09ecd941b4240b971e2e83595a6aa8a265f9d60b |
| hovercard-subject-tag | issue:5208267586 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/nodejs/node/65447/issue_layout |
| twitter:image | https://opengraph.githubassets.com/9c7efa409efeec8f8c128de2dce02c09eb63629a24edae5a284dfaf7a1ae188c/nodejs/node/issues/65447 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/9c7efa409efeec8f8c128de2dce02c09eb63629a24edae5a284dfaf7a1ae188c/nodejs/node/issues/65447 |
| og:image:alt | Version v27.0.0-pre (current main) Platform Linux ari-cachyos 7.1.8-1-cachyos #1 SMP PREEMPT_DYNAMIC Mon, 10 Aug 2026 19:39:40 +0000 x86_64 GNU/Linux Subsystem node:sqlite What steps will reproduce... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | arimxyer |
| hostname | github.com |
| expected-hostname | github.com |
| None | 9d95365dda0576efe9b71f45807595e396bd0ca9286fba5367a05048e6ddf8f2 |
| turbo-cache-control | no-preview |
| go-import | github.com/nodejs/node git https://github.com/nodejs/node.git |
| octolytics-dimension-user_id | 9950313 |
| octolytics-dimension-user_login | nodejs |
| octolytics-dimension-repository_id | 27193779 |
| octolytics-dimension-repository_nwo | nodejs/node |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 27193779 |
| octolytics-dimension-repository_network_root_nwo | nodejs/node |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 98b41fa4b5635ceb45a4c54320fced73817ff290 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
| react-app-name | issues |
Links:
Viewport: width=device-width