diff --git a/app/assets/javascripts/discourse/app/instance-initializers/component-templates.js b/app/assets/javascripts/discourse/app/instance-initializers/component-templates.js
index 776846c925c..5e1d9505e84 100644
--- a/app/assets/javascripts/discourse/app/instance-initializers/component-templates.js
+++ b/app/assets/javascripts/discourse/app/instance-initializers/component-templates.js
@@ -1,9 +1,17 @@
 import DiscourseTemplateMap from "discourse-common/lib/discourse-template-map";
 import * as GlimmerManager from "@glimmer/manager";
 import ClassicComponent from "@ember/component";
+import { isTesting } from "discourse-common/config/environment";
 
 const COLOCATED_TEMPLATE_OVERRIDES = new Map();
 
+let THROW_GJS_ERROR = isTesting();
+
+/** For use in tests/integration/component-templates-test only */
+export function overrideThrowGjsError(value) {
+  THROW_GJS_ERROR = value;
+}
+
 // This patch is not ideal, but Ember does not allow us to change a component template after initial association
 // https://github.com/glimmerjs/glimmer-vm/blob/03a4b55c03/packages/%40glimmer/manager/lib/public/template.ts#L14-L20
 const originalGetTemplate = GlimmerManager.getComponentTemplate;
@@ -34,15 +42,29 @@ export default {
 
       const component = owner.resolveRegistration(`component:${componentName}`);
 
-      if (component && originalGetTemplate(component)) {
-        const finalOverrideModuleName = moduleNames[moduleNames.length - 1];
-        const overrideTemplate = require(finalOverrideModuleName).default;
-
-        COLOCATED_TEMPLATE_OVERRIDES.set(component, overrideTemplate);
-      } else if (!component) {
+      if (!component) {
         // Plugin/theme component template with no backing class.
         // Treat as classic component to emulate pre-template-only-glimmer-component behaviour.
         owner.register(`component:${componentName}`, ClassicComponent);
+        return;
+      }
+
+      const originalTemplate = originalGetTemplate(component);
+      const isStrictMode = originalTemplate?.()?.parsedLayout?.isStrictMode;
+      const finalOverrideModuleName = moduleNames[moduleNames.length - 1];
+
+      if (isStrictMode) {
+        const message = `[${finalOverrideModuleName}] ${componentName} was authored using gjs and its template cannot be overridden. Ignoring override.`;
+        if (THROW_GJS_ERROR) {
+          throw new Error(message);
+        } else {
+          // eslint-disable-next-line no-console
+          console.error(message);
+        }
+      } else if (originalTemplate) {
+        const overrideTemplate = require(finalOverrideModuleName).default;
+
+        COLOCATED_TEMPLATE_OVERRIDES.set(component, overrideTemplate);
       }
     });
   },
diff --git a/app/assets/javascripts/discourse/tests/integration/component-templates-test.js b/app/assets/javascripts/discourse/tests/integration/component-templates-test.gjs
similarity index 87%
rename from app/assets/javascripts/discourse/tests/integration/component-templates-test.js
rename to app/assets/javascripts/discourse/tests/integration/component-templates-test.gjs
index 2aaef532776..330980e13a9 100644
--- a/app/assets/javascripts/discourse/tests/integration/component-templates-test.js
+++ b/app/assets/javascripts/discourse/tests/integration/component-templates-test.gjs
@@ -6,6 +6,8 @@ import { registerTemporaryModule } from "../helpers/temporary-module-helper";
 import { setComponentTemplate } from "@glimmer/manager";
 import Component from "@glimmer/component";
 import { forceMobile, resetMobile } from "discourse/lib/mobile";
+import sinon from "sinon";
+import { overrideThrowGjsError } from "discourse/instance-initializers/component-templates";
 
 class MockColocatedComponent extends Component {}
 setComponentTemplate(hbs`Colocated Original`, MockColocatedComponent);
@@ -266,4 +268,45 @@ module("Integration | Initializers | plugin-component-templates", function () {
         .hasText("Resolved Theme Override", "resolved component correct");
     });
   });
+
+  module("overriding gjs component", function (hooks) {
+    let errorStub;
+
+    hooks.beforeEach(() => {
+      registerTemporaryModule(
+        `discourse/components/mock-gjs-component`,
+        class MyComponent extends Component {
+          <template>
+            <span class="greeting">Hello world</span>
+          </template>
+        }
+      );
+
+      registerTemporaryModule(
+        `discourse/plugins/my-plugin/discourse/templates/components/mock-gjs-component`,
+        hbs`doomed override`
+      );
+
+      errorStub = sinon
+        .stub(console, "error")
+        .withArgs(sinon.match(/mock-gjs-component was authored using gjs/));
+
+      overrideThrowGjsError(false);
+    });
+
+    hooks.afterEach(() => {
+      overrideThrowGjsError(true);
+    });
+
+    setupRenderingTest(hooks);
+
+    test("theme overrides plugin component", async function () {
+      await render(hbs`<MockGjsComponent />`);
+      assert
+        .dom(".greeting")
+        .hasText("Hello world", "renders original implementation");
+
+      sinon.assert.calledOnce(errorStub);
+    });
+  });
 });