diff --git a/doc/api/errors.md b/doc/api/errors.md
index 26685f0ebcdc69..b0ef9b52064a5d 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -889,6 +889,13 @@ provided.
Encoding provided to `TextDecoder()` API was not one of the
[WHATWG Supported Encodings][].
+
+### `ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE`
+
+The JS execution context is not associated with a Node.js environment.
+This may occur when Node.js is used as an embedded library and some hooks
+for the JS engine are not set up properly.
+
### `ERR_FALSY_VALUE_REJECTION`
diff --git a/src/module_wrap.cc b/src/module_wrap.cc
index 2b1708088bf449..b2afefce17eb91 100644
--- a/src/module_wrap.cc
+++ b/src/module_wrap.cc
@@ -451,7 +451,12 @@ MaybeLocal ModuleWrap::ResolveCallback(Local context,
Local specifier,
Local referrer) {
Environment* env = Environment::GetCurrent(context);
- CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
+ if (env == nullptr) {
+ Isolate* isolate = context->GetIsolate();
+ THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(isolate);
+ return MaybeLocal();
+ }
+
Isolate* isolate = env->isolate();
ModuleWrap* dependent = GetFromModule(env, referrer);
@@ -1443,7 +1448,11 @@ static MaybeLocal ImportModuleDynamically(
Local specifier) {
Isolate* iso = context->GetIsolate();
Environment* env = Environment::GetCurrent(context);
- CHECK_NOT_NULL(env); // TODO(addaleax): Handle nullptr here.
+ if (env == nullptr) {
+ THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(iso);
+ return MaybeLocal();
+ }
+
EscapableHandleScope handle_scope(iso);
Local import_callback =
diff --git a/src/node_errors.h b/src/node_errors.h
index a05ce8f6bfb1bd..960cb725323e92 100644
--- a/src/node_errors.h
+++ b/src/node_errors.h
@@ -39,6 +39,7 @@ void OnFatalError(const char* location, const char* message);
V(ERR_CONSTRUCT_CALL_INVALID, TypeError) \
V(ERR_CRYPTO_UNKNOWN_CIPHER, Error) \
V(ERR_CRYPTO_UNKNOWN_DH_GROUP, Error) \
+ V(ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE, Error) \
V(ERR_INVALID_ARG_VALUE, TypeError) \
V(ERR_OSSL_EVP_INVALID_DIGEST, Error) \
V(ERR_INVALID_ARG_TYPE, TypeError) \
@@ -86,28 +87,30 @@ void OnFatalError(const char* location, const char* message);
// Errors with predefined static messages
-#define PREDEFINED_ERROR_MESSAGES(V) \
- V(ERR_BUFFER_CONTEXT_NOT_AVAILABLE, \
- "Buffer is not available for the current Context") \
- V(ERR_CONSTRUCT_CALL_INVALID, "Constructor cannot be called") \
- V(ERR_CONSTRUCT_CALL_REQUIRED, "Cannot call constructor without `new`") \
- V(ERR_CRYPTO_UNKNOWN_CIPHER, "Unknown cipher") \
- V(ERR_CRYPTO_UNKNOWN_DH_GROUP, "Unknown DH group") \
- V(ERR_INVALID_TRANSFER_OBJECT, "Found invalid object in transferList") \
- V(ERR_MEMORY_ALLOCATION_FAILED, "Failed to allocate memory") \
- V(ERR_OSSL_EVP_INVALID_DIGEST, "Invalid digest used") \
- V(ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST, \
- "MessagePort was found in message but not listed in transferList") \
- V(ERR_MISSING_PLATFORM_FOR_WORKER, \
- "The V8 platform used by this instance of Node does not support " \
- "creating Workers") \
- V(ERR_NON_CONTEXT_AWARE_DISABLED, \
- "Loading non context-aware native modules has been disabled") \
- V(ERR_SCRIPT_EXECUTION_INTERRUPTED, \
- "Script execution was interrupted by `SIGINT`") \
- V(ERR_TRANSFERRING_EXTERNALIZED_SHAREDARRAYBUFFER, \
- "Cannot serialize externalized SharedArrayBuffer") \
- V(ERR_TLS_PSK_SET_IDENTIY_HINT_FAILED, "Failed to set PSK identity hint") \
+#define PREDEFINED_ERROR_MESSAGES(V) \
+ V(ERR_BUFFER_CONTEXT_NOT_AVAILABLE, \
+ "Buffer is not available for the current Context") \
+ V(ERR_CONSTRUCT_CALL_INVALID, "Constructor cannot be called") \
+ V(ERR_CONSTRUCT_CALL_REQUIRED, "Cannot call constructor without `new`") \
+ V(ERR_CRYPTO_UNKNOWN_CIPHER, "Unknown cipher") \
+ V(ERR_CRYPTO_UNKNOWN_DH_GROUP, "Unknown DH group") \
+ V(ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE, \
+ "Context not associated with Node.js environment") \
+ V(ERR_INVALID_TRANSFER_OBJECT, "Found invalid object in transferList") \
+ V(ERR_MEMORY_ALLOCATION_FAILED, "Failed to allocate memory") \
+ V(ERR_OSSL_EVP_INVALID_DIGEST, "Invalid digest used") \
+ V(ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST, \
+ "MessagePort was found in message but not listed in transferList") \
+ V(ERR_MISSING_PLATFORM_FOR_WORKER, \
+ "The V8 platform used by this instance of Node does not support " \
+ "creating Workers") \
+ V(ERR_NON_CONTEXT_AWARE_DISABLED, \
+ "Loading non context-aware native modules has been disabled") \
+ V(ERR_SCRIPT_EXECUTION_INTERRUPTED, \
+ "Script execution was interrupted by `SIGINT`") \
+ V(ERR_TRANSFERRING_EXTERNALIZED_SHAREDARRAYBUFFER, \
+ "Cannot serialize externalized SharedArrayBuffer") \
+ V(ERR_TLS_PSK_SET_IDENTIY_HINT_FAILED, "Failed to set PSK identity hint")
#define V(code, message) \
inline v8::Local code(v8::Isolate* isolate) { \