René's URL Explorer Experiment


Title: 24.19.0: --experimental-import-text breaks loader hooks that own with { type: 'text' } · Issue #65210 · nodejs/node · GitHub

Open Graph Title: 24.19.0: --experimental-import-text breaks loader hooks that own with { type: 'text' } · Issue #65210 · nodejs/node

X Title: 24.19.0: --experimental-import-text breaks loader hooks that own with { type: 'text' } · Issue #65210 · nodejs/node

Description: Version 24.19.0 Platform Version: v24.19.0 (works on v24.18.0) Platform: Darwin 24.6.0 arm64 (macOS 15.7), official nvm binaries; originally hit in node:24-alpine on ECS Fargate Subsystem: esm, module Subsystem loader What steps will rep...

Open Graph Description: Version 24.19.0 Platform Version: v24.19.0 (works on v24.18.0) Platform: Darwin 24.6.0 arm64 (macOS 15.7), official nvm binaries; originally hit in node:24-alpine on ECS Fargate Subsystem: esm, mod...

X Description: Version 24.19.0 Platform Version: v24.19.0 (works on v24.18.0) Platform: Darwin 24.6.0 arm64 (macOS 15.7), official nvm binaries; originally hit in node:24-alpine on ECS Fargate Subsystem: esm, mod...

Opengraph URL: https://github.com/nodejs/node/issues/65210

X: @github

direct link

Domain: github.com


Hey, it has json ld scripts:
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"24.19.0: --experimental-import-text breaks loader hooks that own with { type: 'text' }","articleBody":"### Version\n\n24.19.0\n\n### Platform\n\n```text\nVersion: v24.19.0 (works on v24.18.0)\nPlatform: Darwin 24.6.0 arm64 (macOS 15.7), official nvm binaries; originally hit in node:24-alpine on ECS Fargate\nSubsystem: esm, module\n```\n\n### Subsystem\n\nloader\n\n### What steps will reproduce the bug?\n\nThree files:\n\n`asset.txt`\n```\nhello from a text asset\n```\n\n`register-hooks.mjs`\n```js\nimport { registerHooks } from 'node:module';\n\nregisterHooks({\n\tload(url, context, nextLoad) {\n\t\tif (context.importAttributes?.type === 'text') {\n\t\t\t// Use nextLoad purely as a source reader, with a format hint Node does not\n\t\t\t// implement, then return the real module ourselves.\n\t\t\tconst { source } = nextLoad(url, { ...context, format: 'text' });\n\t\t\treturn {\n\t\t\t\tformat: 'module',\n\t\t\t\tsource: `export default ${JSON.stringify(source.toString())}`,\n\t\t\t};\n\t\t}\n\t\treturn nextLoad(url, context);\n\t},\n});\n```\n\n`main.mjs`\n```js\nimport text from './asset.txt' with { type: 'text' };\nconsole.log('loaded via hook:', JSON.stringify(text));\n```\n\nRun:\n```console\n$ node --import ./register-hooks.mjs ./main.mjs\n```\n\nv24.18.0 — works:\n```\nloaded via hook: \"hello from a text asset\\n\"\n```\n\nv24.19.0 — throws `ERR_IMPORT_ATTRIBUTE_UNSUPPORTED` (full output in \"What do you see instead\").\n\nThe same repro written against the deprecated `module.register()` API fails the same way, only through `defaultLoad` instead of `defaultLoadSync`.\n\nSame file tree, no flags, no other changes. `git bisect` isn't needed: the change is https://github.com/nodejs/node/commit/3c1636dabf (#62300, SEMVER-MINOR, first released in v24.19.0). Adding `--experimental-import-text` on v24.19.0 makes the repro pass again on both APIs.\n\n### How often does it reproduce? Is there a required condition?\n\n100% deterministic on v24.19.0 and later (not timing-, load- or platform-dependent)\n\nRequired conditions, all four:\n1. A registered load hook — `module.registerHooks()` or the deprecated `module.register()`; both are affected.\n2. An import carrying `with { type: 'text' }`.\n3. The hook delegating to `nextLoad()` (e.g. to read the file's bytes before transforming it) rather than short-circuiting with its own source. Validation lives in `defaultLoad`/`defaultLoadSync`, at the bottom of the hook chain, so only delegating hooks are hit.\n4. `--experimental-import-text` not set.\n\nIndependent of file extension, of the `format` hint passed to `nextLoad()`, and of whether the hooks are synchronous or asynchronous. Unaffected: hooks that use any other attribute value (`with { type: 'buffer' }` etc.) still take the \"unrecognized type\" path and still work, only the value Node claimed in this PR broke.\n\n### What is the expected behavior? Why is that the expected behavior?\n\nWith `--experimental-import-text` absent, v24.19.0 should behave exactly as v24.18.0 did: `type: 'text'` should reach the `case undefined: break` branch in `validateAttributes`, whose own comment states the intent (\"Ignore attributes for module formats we don't recognize, to allow new formats to be added in the future.\") The attribute should be left for loader hooks to interpret.\n\nThree reasons:\n\n1. A SEMVER-MINOR feature behind an experimental flag should be inert when the flag is off. #62300 is described as purely additive, but its flag-off path is a new hard throw on input that previously worked. If the feature is experimental, the rejection cannot be unconditional.\n2. That tolerance branch is the only mechanism loader hooks have for owning an attribute type. #51128 asked for a real one (a hook for custom attributes, or a way to disable built-in validation when hooks are registered) and was closed without providing it. Hooks were left with the ignore-unknown-types path and are now being broken for having used it.\n3. Reading source via `nextLoad()` is the documented way for a load hook to get a file's contents. The break specifically punishes hooks that follow that guidance; short-circuiting hooks that read the file themselves are unaffected.\n\n### What do you see instead?\n\n`registerHooks()` on v24.19.0:\n\n```\nnode:internal/modules/esm/assert:73\n    throw new ERR_IMPORT_ATTRIBUTE_UNSUPPORTED('type', importAttributes.type, url);\n          ^\n\nTypeError [ERR_IMPORT_ATTRIBUTE_UNSUPPORTED]: Import attribute \"type\" with value \"text\" is not supported in file:///private/tmp/repro-62300/asset.txt\n    at validateAttributes (node:internal/modules/esm/assert:73:11)\n    at defaultLoadSync (node:internal/modules/esm/load:163:3)\n    at #loadAndMaybeBlockOnLoaderThread (node:internal/modules/esm/loader:802:12)\n    at nextStep (node:internal/modules/customization_hooks:189:26)\n    at load (file:///private/tmp/repro-62300/register-hooks.mjs:8:23)\n    at nextStep (node:internal/modules/customization_hooks:189:26)\n    at loadWithHooks (node:internal/modules/customization_hooks:374:18)\n    at #loadSync (node:internal/modules/esm/loader:825:16)\n    at ModuleLoader.load (node:internal/modules/esm/loader:783:26)\n    at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:494:31) {\n  code: 'ERR_IMPORT_ATTRIBUTE_UNSUPPORTED'\n}\n\nNode.js v24.19.0\n```\n\nWith the deprecated `module.register()`, the same error arrives via `defaultLoad (node:internal/modules/esm/load:108:3)`.\n\nThe throw happens inside the hook's own `nextLoad()` call, so the hook never gets to return. The message names the asset URL and the attribute, but says nothing about the new flag or about the registered hooks, so from an application's point of view the import simply stops working after a patch-level base-image bump.\n\n### Additional information\n\nRoot cause, in `lib/internal/modules/esm/assert.js` as of #62300:\n\n- `formatTypeMap` gained `'text': 'text'`, so `validType` is no longer `undefined` for\n  the text format, and\n- a new unconditional check throws before the switch:\n\n  ```js\n  if (validType !== undefined &&\n    importAttributes.type === 'text' &&\n    !getOptionValue('--experimental-import-text')) {\n    throw new ERR_IMPORT_ATTRIBUTE_UNSUPPORTED('type', importAttributes.type, url);\n  }\n  ```\n\nSetting `--experimental-import-text` does make the repro pass, so the flag is a workaround — but it is the wrong requirement: an application has to opt into an experimental module feature it does not use, on every entrypoint (`node`, test runners, workers, tooling), purely to stop Node from rejecting an attribute its own loader handles. It is also unavailable on every release line that predates the flag, so there is no single spelling that runs on 24.18 and 24.19.\n\nReal-world impact: a service that loads ~33 email-template asset sets through `with { type: 'text' }` and a registered load hook went from healthy on 24.18 to crash-looping on the first template on 24.19, dying before any application code ran. Because the image is `node:24-alpine`, this arrived with a rebuild rather than a version bump, one day after 24.19.0 was released, and cost a production rollback. Mitigation was to pin the base image, then delete the import-attribute loaders entirely and read the assets with `fs` + `new URL(..., import.meta.url)` across 47 files.\n\nRequests:\n1. Make the flag-off path inert — when `--experimental-import-text` is not set, do not add `'text'` to the recognized-format map and do not throw; fall through to the unrecognized-attribute path so hooks keep working as on 24.18.\n2. Give hooks a supported way to claim attribute types (#51128) before Node claims further type names, otherwise each new built-in type is another silent break for whoever already used that name.\n3. Note the behaviour change for loader-hook consumers in the changelog, and add regression tests covering a registered load hook that handles `with { type: 'text' }` without the flag, for both `module.registerHooks()` (`defaultLoadSync`) and `module.register()` (`defaultLoad`). The PR's tests only cover flag-on and flag-off without hooks.","author":{"url":"https://github.com/richterdennis","@type":"Person","name":"richterdennis"},"datePublished":"2026-08-11T07:26:37Z","url":"https://github.com/nodejs/node/issues/65210"}

react-profiling0
react-import-mapreact,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-controllervoltron_issues_fragments
route-actionissue_layout
fetch-noncev2:eab9c34e-aac8-08db-9302-1ad780445c90
current-catalog-service-hash81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114
request-id836A:D1DAA:626780:85A73D:6AED2512
html-safe-nonceb5efb4ef22cfbf1b1b13fc4b7e0dd4e5182564b35e0ff13b4985740d6605cccb
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4MzZBOkQxREFBOjYyNjc4MDo4NUE3M0Q6NkFFRDI1MTIiLCJ2aXNpdG9yX2lkIjoiMjMxMzM0NDY5MTA4MTEyNzE4NiIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9
visitor-hmac9d0024539eaeeee306771a4813442c096377cc56a34719baac91f6da1f7faf52
hovercard-subject-tagissue:5117753781
github-keyboard-shortcutsrepository,issues,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///voltron/issues_fragments/issue_layout
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/nodejs/node/65210/issue_layout
twitter:imagehttps://opengraph.githubassets.com/c9dfb36968b2e728ad1081b1850a069b9b9464875509791c17021bb2bae1f430/nodejs/node/issues/65210
twitter:cardsummary_large_image
og:imagehttps://opengraph.githubassets.com/c9dfb36968b2e728ad1081b1850a069b9b9464875509791c17021bb2bae1f430/nodejs/node/issues/65210
og:image:altVersion 24.19.0 Platform Version: v24.19.0 (works on v24.18.0) Platform: Darwin 24.6.0 arm64 (macOS 15.7), official nvm binaries; originally hit in node:24-alpine on ECS Fargate Subsystem: esm, mod...
og:image:width1200
og:image:height600
og:site_nameGitHub
og:typeobject
og:author:usernamerichterdennis
hostnamegithub.com
expected-hostnamegithub.com
Nonee3e0f7f63e50c6fe879198a93a0a023a648ecc0a5e9bc3b5e033ac57172237e6
turbo-cache-controlno-preview
go-importgithub.com/nodejs/node git https://github.com/nodejs/node.git
octolytics-dimension-user_id9950313
octolytics-dimension-user_loginnodejs
octolytics-dimension-repository_id27193779
octolytics-dimension-repository_nwonodejs/node
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id27193779
octolytics-dimension-repository_network_root_nwonodejs/node
turbo-body-classeslogged-out env-production page-responsive
disable-turbofalse
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release707a24b346ac8a82878b9c084efaa38a997660cb
ui-targetfull
theme-color#1e2327
color-schemelight dark
react-app-nameissues

Links:

Skip to contenthttps://github.com/nodejs/node/issues/65210#start-of-content
https://github.com/
Sign inhttps://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fissues%2F65210
GitHubRepository hosting, code review, and collaborationhttps://github.com/platform
CopilotAI coding agent for tasks, projects, and automated workhttps://github.com/features/copilot
ActionsCI/CD and automationhttps://github.com/features/actions
Code QualityQuality analysis, fixes, and enforcementhttps://github.com/features/code-quality
CodespacesCloud development environmentshttps://github.com/features/codespaces
Code SecurityVulnerability detection and remediationhttps://github.com/security/advanced-security/code-security
Secret ProtectionSecret scanning and leak preventionhttps://github.com/security/advanced-security/secret-protection
All Featureshttps://github.com/features
Documentationhttps://docs.github.com/en
Traininghttps://learn.github.com/skills
Certificationshttps://learn.github.com/credentials
Build with Copilothttps://github.com/features/ai
Customize Copilothttps://docs.github.com/en/copilot/how-tos/copilot-on-github/customize-copilot/customize-copilot-overview
Integrationshttps://github.com/marketplace
Trending reposhttps://github.com/trending
GitHub Sponsorshttps://github.com/open-source/sponsors
Developer articleshttps://github.com/resources/articles
ChangelogYour source for the latest features, improvements, and fixes across GitHub products, all in one place.https://github.blog/changelog/
Enterpriseshttps://github.com/enterprise
Teamhttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
See all industrieshttps://github.com/solutions/industry
Why GitHubhttps://github.com/why-github
Customer Storieshttps://github.com/customer-stories
Business insightshttps://github.com/solutions/executive-insights
Trust Centerhttps://github.com/trust-center
GitHub Advanced SecurityEnterprise-grade code securityhttps://github.com/security/advanced-security
Copilot for businessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/enterprise/premium-support
Documentationhttps://docs.github.com/en
Resource centerhttps://github.com/resources
Bloghttps://github.blog/
Events & webinarshttps://github.com/resources/events
Community Forumhttps://github.com/orgs/community/discussions
Customer Storieshttps://github.com/customer-stories
Integrationshttps://github.com/marketplace
Customer supporthttps://help.github.com/
Traininghttps://learn.github.com/skills
GitHub Statushttps://www.githubstatus.com/
Abouthttps://github.com/about
Partnershttps://github.com/partners
Changeloghttps://github.blog/changelog/
GitHub UniverseThe event for developers, by developers — talks, workshops, and what’s next for GitHub.https://githubuniverse.com/
Pricinghttps://github.com/pricing
Sign inhttps://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fnodejs%2Fnode%2Fissues%2F65210
Sign uphttps://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fvoltron%2Fissues_fragments%2Fissue_layout&source=header-repo&source_repo=nodejs%2Fnode
Reloadhttps://github.com/nodejs/node/issues/65210
Reloadhttps://github.com/nodejs/node/issues/65210
Reloadhttps://github.com/nodejs/node/issues/65210
nodejshttps://github.com/nodejs
nodehttps://github.com/nodejs/node
Codehttps://github.com/nodejs/node
Issues657 (657)https://github.com/nodejs/node/issues
Pull requests666 (666)https://github.com/nodejs/node/pulls
Actionshttps://github.com/nodejs/node/actions
Projectshttps://github.com/nodejs/node/projects
Security and qualityhttps://github.com/nodejs/node/security
Insightshttps://github.com/nodejs/node/pulse
https://github.com/nodejs/node
New issuehttps://github.com/login?return_to=https://github.com/nodejs/node/issues/65210
New issuehttps://github.com/login?return_to=https://github.com/nodejs/node/issues/65210
24.19.0: --experimental-import-text breaks loader hooks that own with { type: 'text' }https://github.com/nodejs/node/issues/65210#top
https://github.com/richterdennis
richterdennishttps://github.com/richterdennis
on Aug 11, 2026https://github.com/nodejs/node/issues/65210#issue-5117753781
3c1636dabfhttps://github.com/nodejs/node/commit/3c1636dabf
#62300https://github.com/nodejs/node/pull/62300
loader: add experimental text import #62300https://github.com/nodejs/node/pull/62300
custom Import attributes with esm hooks #51128https://github.com/nodejs/node/issues/51128
#62300https://github.com/nodejs/node/pull/62300
custom Import attributes with esm hooks #51128https://github.com/nodejs/node/issues/51128
https://github.com/aduh95
aduh95https://github.com/aduh95
on Aug 11, 2026https://github.com/nodejs/node/issues/65210#issuecomment-5250530444
#64992https://github.com/nodejs/node/pull/64992
aduh95https://github.com/aduh95
completedhttps://github.com/nodejs/node/issues?q=is%3Aissue%20state%3Aclosed%20archived%3Afalse%20reason%3Acompleted
on Aug 11, 2026https://github.com/nodejs/node/issues/65210#event-29266886214
Sign up for freehttps://github.com/signup?return_to=https://github.com/nodejs/node/issues/65210
Sign in to commenthttps://github.com/login?return_to=https://github.com/nodejs/node/issues/65210
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.