monaco-react icon indicating copy to clipboard operation
monaco-react copied to clipboard

Uncaught promise when using useMonaco()

Open willdady opened this issue 3 years ago • 16 comments

When I add these lines:

  const monaco = useMonaco();
  useEffect(() => {
    if (monaco) {
      console.log('here is the monaco instance:', monaco);
    }
  }, [monaco]);

I get the following error in my browser console:

Uncaught (in promise) {type: 'cancelation', msg: 'operation is manually canceled'}

willdady avatar Jan 04 '23 22:01 willdady

Do you use React 18 with strict mode?

suren-atoyan avatar Jan 05 '23 15:01 suren-atoyan

Yes, 18.2. It's a Next.js (13.0.7) app. Not sure about strict mode.

willdady avatar Jan 05 '23 23:01 willdady

could you please check this?

suren-atoyan avatar Jan 06 '23 05:01 suren-atoyan

I get the same error in the console. I am using React 18 in strict mode but not Next.js

stefanbugge avatar Jan 06 '23 09:01 stefanbugge

Same error but probably a different case with React 18 and no Next.js.

  • Custom loader based on this
  • React.StrictMode
  • Loading it with React.lazy()

If I don't load it lazy it would work but that's not an option in my project.


Works:

  • CDN + No strict mode
  • Custom loader + Strict mode

Doesn't work:

  • CDN + Strict mode
  • Custom loader + Strict mode + Lazy

cbn-falias avatar Jan 19 '23 16:01 cbn-falias

I am also getting the same error. I am using NextJS 13 with the useMonaco() hook, with Strict Mode: On. Btw, I am already using the "use client" directive on top of the code given below to render the component client side.

image Here's how I am using it. This usage also gives the "default props on functional components are depreciated" warning

AtharvaUmbarkar avatar Feb 12 '23 14:02 AtharvaUmbarkar

We are encountering this issue as well: https://github.com/aiven/klaw/issues/1464

I have been able to ascertain that this console.error seems to happen unconditionally when calling useMonaco: in this minimal example, it seems to always be there https://codesandbox.io/s/sleepy-moore-3mct7n?file=/src/App.js:123-132

mathieu-anderson avatar Jul 13 '23 06:07 mathieu-anderson

I also ascertained that the console.error only happens when using StrictMode.

mathieu-anderson avatar Jul 14 '23 08:07 mathieu-anderson

The same error with React 18 in strict mode, not Next.js

wb-wenbei avatar Feb 06 '24 07:02 wb-wenbei

I get the same error when updating the JSON schema with useEffect().

  • React 18.3.1
  • Strict mode: off
  • @monaco-editor/react: 4.6.0
import React, { useEffect } from 'react';
import Editor, { useMonaco } from '@monaco-editor/react';

interface IConfigEditor {
    value: string;
    path?: string;
    schemaUri?: string;
}

export const ConfigEditor: React.FC<IConfigEditor> = props => {
    const monaco = useMonaco();

    useEffect(() => {
        if (monaco && props.path && props.schemaUri) {
            monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
                validate: true,
                enableSchemaRequest: true,
                schemas: [
                    {
                        uri: props.schemaUri,
                        fileMatch: [props.path],
                    },
                ],
            });
        }
    }, [monaco, props.path, props.schemaUri]);
    return (
        <Editor
            path={props.path}
            language="json"
            value={props.value}
        />
    )
};

Edit: I solved the problem in non-strict mode by using the beforeMount handler of the Editor component to initialize the schemas and a useEffect() hook to update the schema list. It still fails in strict mode, though.

moiri avatar Aug 28 '24 06:08 moiri

Solved by replacing the default useMonaco with a custom hook that safely initializes Monaco in React Strict Mode environments (like Next.js). It ensures:

  • No double-loading of the Monaco instance.
  • Proper cleanup and error handling.
  • Compatibility with hydration and re-renders.

✅ Custom hook implementation:

// hooks/useCustomMonaco.ts
import { useState, useRef, useEffect } from "react";
import * as monaco from "monaco-editor";
import { loader } from "@monaco-editor/react";

export function useCustomMonaco() {
  const [monacoInstance, setMonacoInstance] = useState<typeof monaco | null>(null);
  const mountedRef = useRef(true);
  const loaderRef = useRef<any>(null);

  useEffect(() => {
    const instance = loader.__getMonacoInstance();

    if (instance) {
      setMonacoInstance(instance);
      return;
    }

    if (!loaderRef.current) {
      loader.config({
        "vs/nls": { availableLanguages: {} },
      });

      try {
        loaderRef.current = loader.init();

        loaderRef.current
          .then((monacoApi: typeof monaco) => {
            if (mountedRef.current) {
              setMonacoInstance(monacoApi);
            }
          })
          .catch((error: any) => {
            if (mountedRef.current && error.type !== "cancelation") {
              console.error("Monaco initialization error:", error);
            }
          });
      } catch (err) {
        console.error("Failed to initialize Monaco:", err);
      }
    }

    return () => {
      mountedRef.current = false;
    };
  }, []);

  return monacoInstance;
}

export default useCustomMonaco;

davidg0022 avatar Apr 01 '25 07:04 davidg0022

This issue has been marked as stale due to inactivity. It will be closed in 7 days unless further activity occurs.

github-actions[bot] avatar Sep 29 '25 00:09 github-actions[bot]

This issue still persists and should be addressed.

dlindahl avatar Sep 29 '25 16:09 dlindahl

This issue still persists and should be addressed.

@dlindahl could you please confirm that you use useMonaco and StrictMode?

If so, can you please try David's solution?

suren-atoyan avatar Oct 01 '25 15:10 suren-atoyan

Hello all, Sorry for the late reply. I had faced this issue ~2yrs ago. Don't have time currently to check/remember this in detail. Can check this in a few days, but if @dlindahl's solution seems good. You can include it natively with a prop ig to make it easily accessible for all. Afair your library was the only one which allowed us to customise everything as needed, so i think this would be a good addition.

AtharvaUmbarkar avatar Oct 01 '25 16:10 AtharvaUmbarkar

@suren-atoyan I am using useMonaco. I am NOT using StrictMode.

dlindahl avatar Oct 06 '25 16:10 dlindahl