Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

TypeError: Cannot add property source, object is not extensible #57030

Closed
bouzlibop opened this issue Feb 13, 2025 · 6 comments · Fixed by #57056
Closed

TypeError: Cannot add property source, object is not extensible #57030

bouzlibop opened this issue Feb 13, 2025 · 6 comments · Fixed by #57056
Labels
doc Issues and PRs related to the documentations. loaders Issues and PRs related to ES module loaders

Comments

@bouzlibop
Copy link

Version

v23.7.0

Platform

Darwin MacBookPro.T-Mobile 24.3.0 Darwin Kernel Version 24.3.0: Thu Jan  2 20:24:16 PST 2025; root:xnu-11215.81.4~3/RELEASE_ARM64_T6000 arm6

Subsystem

No response

What steps will reproduce the bug?

To reproduce the issue try running the synchronous version of the transpilation example.

How often does it reproduce? Is there a required condition?

100%

What is the expected behavior? Why is that the expected behavior?

I would expect the code from the API docs to run without any errors.

What do you see instead?

node:internal/modules/esm/load:173
    context.source = source;
                   ^

TypeError: Cannot add property source, object is not extensible

Additional information

No response

@aduh95
Copy link
Contributor

aduh95 commented Feb 13, 2025

/cc @joyeecheung

@joyeecheung
Copy link
Member

joyeecheung commented Feb 13, 2025

It seems both the async version and the sync version of the example are incorrect:

  1. Using nextLoad() on .coffee would lead to ERR_UNKNOWN_FILE_EXTENSION, which I guess is working as intended, though personally I think this is something we need to provide a mitigation for in the API (e.g. add an argument in the context to imply just reading a buffer from disk as fallback for all the unknown extensions, or TBH I am not even sure why we even need ERR_UNKNOWN_FILE_EXTENSION instead of just doing this read for all unknown extensions)
  2. Both examples do not pass context to the nextLoad hook, which would lead to an error.

@joyeecheung
Copy link
Member

Also both versions could not produce valid module types, since the documentation does not mention adding a package.json with a type field, so the module detection code would now fail with ERR_UNKNOWN_FILE_EXTENSION since it doesn't know how to detect types from .coffee (I feel that ERR_UNKNOWN_FILE_EXTENSION is really counterproductive at this point, why do we have this error? @nodejs/loaders )

@joyeecheung
Copy link
Member

joyeecheung commented Feb 13, 2025

Actually I remember this was one the reasons I left

https://github.com/nodejs/node/blob/main/doc/api/module.md?plain=1#L1348-L1350

because it seems the examples have been broken for a while due to lack of testing....

@joyeecheung joyeecheung added doc Issues and PRs related to the documentations. loaders Issues and PRs related to ES module loaders labels Feb 14, 2025
@bouzlibop
Copy link
Author

bouzlibop commented Feb 14, 2025

@joyeecheung I believe the async hooks version handles default context properly and sync does not. Consider following minimal example:

  • package.json

    {
      "name": "test1",
      "version": "1.0.0",
      "type": "module"
    }
  • a.js

    import b from './b.js';
    console.log(b);
  • b.js

    export default 2;
  • async-hook.js

    export async function load(url, context, nextLoad) {
     return nextLoad(url);
    }
  • sync-hook.js

    import { registerHooks } from 'node:module';
    
    export function load(url, context, nextLoad) {
      return nextLoad(url);
    }
    
    registerHooks({ load });

Now running the async hook finishes without any errors:

$ node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./async-hook.js"));' ./a.js
2

In contrast if I try to run the sync hook I get an error:

$ node --import ./sync-hook.js ./a.js
node:internal/modules/esm/load:173
    context.source = source;
                   ^

TypeError: Cannot add property source, object is not extensible

I would assume that both would have the same results. Why is that the sync version throws? 🤔

@joyeecheung
Copy link
Member

According to discussions in #57037 the sync hooks are currently making the context parameter mandatory (as a result an internal context is created in the absence of that, which is frozen it seems). Until we fix it internally, you could make it work by always passing the context parameter to nextLoad()

nodejs-github-bot pushed a commit that referenced this issue Feb 16, 2025
The loader hooks examples have been broken for a while:

1. The nextLoad() hook cannot be used on a .coffee file that ends
   up going to the default load step without an explict format,
   which would cause a ERR_UNKNOWN_FILE_EXTENSION. Mention
   adding a package.json with a type field to work around it
   in the example.
2. Pass the context parameter to the nextLoad() invocation and
   document that context.format is mandatory when module type
   is not explicitly inferrable from the module.
3. Correct the getPackageType() implementation which returns
   false instead of undefined in the absence of an explict format,
   which is not a valid type for format.

PR-URL: #57037
Refs: #57030
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
targos pushed a commit that referenced this issue Feb 17, 2025
The loader hooks examples have been broken for a while:

1. The nextLoad() hook cannot be used on a .coffee file that ends
   up going to the default load step without an explict format,
   which would cause a ERR_UNKNOWN_FILE_EXTENSION. Mention
   adding a package.json with a type field to work around it
   in the example.
2. Pass the context parameter to the nextLoad() invocation and
   document that context.format is mandatory when module type
   is not explicitly inferrable from the module.
3. Correct the getPackageType() implementation which returns
   false instead of undefined in the absence of an explict format,
   which is not a valid type for format.

PR-URL: #57037
Refs: #57030
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
joyeecheung added a commit to joyeecheung/node that referenced this issue Feb 18, 2025
This aligns the behavior of synchronous hooks with asynchronous
hooks by allowing omission of the context parameter in the
invocation of next hooks. The contexts are merged along the
chain.

PR-URL: nodejs#57056
Fixes: nodejs#57030
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
acidiney pushed a commit to acidiney/node that referenced this issue Feb 23, 2025
The loader hooks examples have been broken for a while:

1. The nextLoad() hook cannot be used on a .coffee file that ends
   up going to the default load step without an explict format,
   which would cause a ERR_UNKNOWN_FILE_EXTENSION. Mention
   adding a package.json with a type field to work around it
   in the example.
2. Pass the context parameter to the nextLoad() invocation and
   document that context.format is mandatory when module type
   is not explicitly inferrable from the module.
3. Correct the getPackageType() implementation which returns
   false instead of undefined in the absence of an explict format,
   which is not a valid type for format.

PR-URL: nodejs#57037
Refs: nodejs#57030
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
acidiney pushed a commit to acidiney/node that referenced this issue Feb 23, 2025
This aligns the behavior of synchronous hooks with asynchronous
hooks by allowing omission of the context parameter in the
invocation of next hooks. The contexts are merged along the
chain.

PR-URL: nodejs#57056
Fixes: nodejs#57030
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
targos pushed a commit that referenced this issue Feb 24, 2025
This aligns the behavior of synchronous hooks with asynchronous
hooks by allowing omission of the context parameter in the
invocation of next hooks. The contexts are merged along the
chain.

PR-URL: #57056
Fixes: #57030
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
doc Issues and PRs related to the documentations. loaders Issues and PRs related to ES module loaders
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants