diff --git a/.changeset/fn-8820-message-composer-mobile-width.md b/.changeset/fn-8820-message-composer-mobile-width.md
new file mode 100644
index 0000000000..b5b6d338d7
--- /dev/null
+++ b/.changeset/fn-8820-message-composer-mobile-width.md
@@ -0,0 +1,7 @@
+---
+"@runfusion/fusion": patch
+---
+
+summary: Keep Messages structure selection within narrow mobile composers.
+category: fix
+dev: Shared MessageComposer sizing now contains long structure labels in full-page and modal Messages.
diff --git a/packages/dashboard/app/components/MessageComposer.css b/packages/dashboard/app/components/MessageComposer.css
index 9f173e81d0..6d03e2208f 100644
--- a/packages/dashboard/app/components/MessageComposer.css
+++ b/packages/dashboard/app/components/MessageComposer.css
@@ -15,7 +15,24 @@
flex: 1 1 auto;
}
+/*
+FNXC:MessageComposerMobileWidth 2026-08-07-03:22:
+Long native-structure kind and label values must not give the shared Messages picker an intrinsic width that escapes a narrow composer. The shared select remains shrinkable at every breakpoint; mobile explicitly fills its stacked field so both full-page and modal callers inherit containment.
+*/
+.message-composer-structure-controls .message-composer-select {
+ min-width: 0;
+ width: 100%;
+ max-width: 100%;
+}
+
@media (max-width: 768px) {
+ .message-composer-field--structures,
+ .message-composer-structure-controls {
+ width: 100%;
+ max-width: 100%;
+ min-width: 0;
+ }
+
.message-composer-structure-list > li {
align-items: stretch;
}
diff --git a/packages/dashboard/app/components/__tests__/MessageComposer.mobile-width.test.ts b/packages/dashboard/app/components/__tests__/MessageComposer.mobile-width.test.ts
new file mode 100644
index 0000000000..f6bf247b92
--- /dev/null
+++ b/packages/dashboard/app/components/__tests__/MessageComposer.mobile-width.test.ts
@@ -0,0 +1,34 @@
+import { describe, expect, it } from "vitest";
+import { loadComponentCss, readAppFile } from "../../test/cssFixture";
+
+function getRuleBlock(css: string, selector: string) {
+ const escapedSelector = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
+ return css.match(new RegExp(`${escapedSelector}\\s*\\{([^}]*)\\}`))?.[1] ?? "";
+}
+
+describe("MessageComposer mobile structure picker width", () => {
+ const css = loadComponentCss("MessageComposer.css");
+
+ it("keeps the long-label select shrinkable in the shared desktop base rule", () => {
+ const selectRule = getRuleBlock(css, ".message-composer-structure-controls .message-composer-select");
+
+ expect(selectRule).toMatch(/min-width\s*:\s*0/);
+ expect(selectRule).toMatch(/width\s*:\s*100%/);
+ expect(selectRule).toMatch(/max-width\s*:\s*100%/);
+ });
+
+ it("fills the stacked mobile field without a caller-specific Messages patch", () => {
+ const mobileCss = css.slice(css.indexOf("@media (max-width: 768px)"));
+ const mobileFieldRule = getRuleBlock(mobileCss, ".message-composer-field--structures,\n .message-composer-structure-controls");
+
+ expect(mobileFieldRule).toMatch(/min-width\s*:\s*0/);
+ expect(mobileFieldRule).toMatch(/width\s*:\s*100%/);
+ expect(mobileFieldRule).toMatch(/max-width\s*:\s*100%/);
+
+ for (const caller of ["MailboxView.tsx", "MailboxModal.tsx"]) {
+ const source = readAppFile(`components/${caller}`);
+ expect(source).toContain('from "./MessageComposer"');
+ expect(source).toContain("nativeStructureCandidates={nativeStructureCandidates}");
+ }
+ });
+});
diff --git a/packages/dashboard/app/components/__tests__/MessageComposer.test.tsx b/packages/dashboard/app/components/__tests__/MessageComposer.test.tsx
index f61dd0d76a..03a29a0098 100644
--- a/packages/dashboard/app/components/__tests__/MessageComposer.test.tsx
+++ b/packages/dashboard/app/components/__tests__/MessageComposer.test.tsx
@@ -147,6 +147,20 @@ describe("MessageComposer", () => {
expect(screen.getByText("No structures available")).toBeInTheDocument();
});
+ it("preserves a long structure label when attaching from the shared picker", () => {
+ const longLabel = "A deliberately long structure label that must remain available without changing attachment metadata";
+ render();
+
+ const picker = screen.getByTestId("message-composer-attach-structure");
+ expect(picker).not.toBeDisabled();
+ expect(picker).toHaveTextContent(`mission-with-a-deliberately-long-kind: ${longLabel}`);
+ fireEvent.change(picker, { target: { value: "0" } });
+
+ expect(screen.getByTestId("message-composer-attached-structures")).toHaveTextContent(longLabel);
+ });
+
it("disables send button when content is empty", () => {
render();
const sendBtn = screen.getByTestId("message-composer-send");