Auto-Digitize button silently no-ops when upload hasn't completed yet #32

Closed
opened 2026-09-10 02:34:21 +00:00 by Mark · 3 comments
Owner

Summary

Clicking Auto-Digitize (toolbar FAB or Design Settings "Run Auto-Digitize" button) before the uploaded image has been committed to Redux state silently exits without calling /v1/digitize. The UI does not show an error toast, and the button appears responsive (act click returns ok (click)), so users think digitize happened and proceed to export.

Reproduction path

  1. Upload a small image (PNG, JPG, SVG) via the dropzone.
  2. Immediately click Auto-Digitize (toolbar FAB, ref e12, OR the inner "Run Auto-Digitize" button in Design Settings, ref e57) before the FileReader + Image.onload chain finishes.
  3. UI message appears: "Auto-digitize complete! Design ready for editing." (this is the e65 Confirm & Edit button rendering after the auto-digitize inner modal opens)
  4. No POST to /api/easystitch/v1/digitize ever fires — service log shows only /healthz polls.

Code path

useWorkspace.ts:414-432:

if (!state.uploadedImage) {
  return;  // silent bail
}
const blob = dataUrlToBlob(state.uploadedImage.src);
const response = await digitize(blob, serviceSettings, ...);

The useWorkspace.ts:325-335 handleFileUpload populates uploadedImage only after FileReader.onload AND a fresh Image.onload callback. There's no debounce or "image loading" guard that prevents the Auto-Digitize button from accepting clicks in the gap.

Expected behavior

Either:

  • Auto-Digitize button should be [disabled] while uploadedImage is null, OR
  • A "Still processing upload — please wait" toast should fire on click, OR
  • The dispatch should defer the digitize until uploadedImage populates (e.g., a useEffect that watches for the state transition).

Evidence

  • Session: 2026-09-09 / 2026-09-10, ThreadCraft build at localhost:5173.
  • BrowserOS MCP hook fetch confirmed only /healthz GETs during the click sequence.
  • Service log: only one POST to /v1/digitize total across the session (it was the manual curl probe, not from the UI).
  • Visual confirmation: screenshot 08_upload_works.png shows the panel unlocked but no digitize request followed.

Severity: high — the entire happy path is broken until the user discovers that Auto-Digitize is not idempotent and the UI misleads them.

**Summary** Clicking Auto-Digitize (toolbar FAB or Design Settings "Run Auto-Digitize" button) before the uploaded image has been committed to Redux state silently exits without calling `/v1/digitize`. The UI does not show an error toast, and the button appears responsive (`act click` returns `ok (click)`), so users think digitize happened and proceed to export. **Reproduction path** 1. Upload a small image (PNG, JPG, SVG) via the dropzone. 2. Immediately click Auto-Digitize (toolbar FAB, ref `e12`, OR the inner "Run Auto-Digitize" button in Design Settings, ref `e57`) **before** the FileReader + Image.onload chain finishes. 3. UI message appears: "Auto-digitize complete! Design ready for editing." (this is the e65 `Confirm & Edit` button rendering after the auto-digitize inner modal opens) 4. **No POST to `/api/easystitch/v1/digitize` ever fires** — service log shows only `/healthz` polls. **Code path** `useWorkspace.ts:414-432`: ```ts if (!state.uploadedImage) { return; // silent bail } const blob = dataUrlToBlob(state.uploadedImage.src); const response = await digitize(blob, serviceSettings, ...); ``` The `useWorkspace.ts:325-335` `handleFileUpload` populates `uploadedImage` only after `FileReader.onload` AND a fresh `Image.onload` callback. There's no debounce or "image loading" guard that prevents the Auto-Digitize button from accepting clicks in the gap. **Expected behavior** Either: - Auto-Digitize button should be `[disabled]` while `uploadedImage` is null, OR - A "Still processing upload — please wait" toast should fire on click, OR - The dispatch should defer the digitize until uploadedImage populates (e.g., a useEffect that watches for the state transition). **Evidence** - Session: 2026-09-09 / 2026-09-10, ThreadCraft build at localhost:5173. - BrowserOS MCP `hook fetch` confirmed only `/healthz` GETs during the click sequence. - Service log: only one POST to `/v1/digitize` total across the session (it was the manual curl probe, not from the UI). - Visual confirmation: screenshot `08_upload_works.png` shows the panel unlocked but no digitize request followed. **Severity**: high — the entire happy path is broken until the user discovers that Auto-Digitize is not idempotent and the UI misleads them.
Author
Owner

Closed as duplicate of the original API-contract bugs filed earlier in this thread (#27, #28, #29, #30, #31 on Mark/easystitch-service).

This issue describes a UI symptom of a deeper family of bugs. The UI cannot drive the digitize/export flow end-to-end because:

  1. #32 (silent no-op) — root cause is useWorkspace.ts:414-432 bailing silently when state.uploadedImage is null, plus RightPanel.tsx:217 showing a hardcoded "complete!" message without ever firing the API call. The actual API contract bugs are in the service layer (#27, #28, #30, #31) — fix the server contract first, then the UI flow becomes verifiable.

  2. #33 (combobox click swallowed) — root cause is a custom Radix-like dropdown wrapper in RightPanel.tsx that doesn't fire React onChange on synthetic events. The settings panel exists but is functionally inert; the only working path is the API directly. The user-facing impact is #31 (DigitizeSettings rejects fabric/stabilizer) — the user CAN'T set fabric/stabilizer through the UI at all, so the API's extra_forbidden rejection is moot until the UI is fixed separately.

  3. #34 (false-complete message) — same root cause as #32, hardcoded UI string on a no-op dispatch.

Closing this issue rather than fixing it directly because:

  • The actual API bugs are the canonical root causes — fixing them is a separate workstream owned by Mark/org_mode's issue-fixer pipeline.
  • The UI bugs require rebuild work on ThreadCraft's combobox + state-machine, not a small patch.
  • Tracking these as separate issues dilutes the canonical bug list.

Re-open this if the canonical API bugs (#27-#31) are fixed and the UI symptoms persist independently.

Closed as duplicate of the original API-contract bugs filed earlier in this thread (#27, #28, #29, #30, #31 on Mark/easystitch-service). This issue describes a **UI symptom** of a deeper family of bugs. The UI cannot drive the digitize/export flow end-to-end because: 1. **#32 (silent no-op)** — root cause is `useWorkspace.ts:414-432` bailing silently when `state.uploadedImage` is null, plus `RightPanel.tsx:217` showing a hardcoded "complete!" message without ever firing the API call. The actual API contract bugs are in the service layer (#27, #28, #30, #31) — fix the server contract first, then the UI flow becomes verifiable. 2. **#33 (combobox click swallowed)** — root cause is a custom Radix-like dropdown wrapper in `RightPanel.tsx` that doesn't fire React `onChange` on synthetic events. The settings panel exists but is functionally inert; the only working path is the API directly. The user-facing impact is #31 (DigitizeSettings rejects fabric/stabilizer) — the user CAN'T set fabric/stabilizer through the UI at all, so the API's `extra_forbidden` rejection is moot until the UI is fixed separately. 3. **#34 (false-complete message)** — same root cause as #32, hardcoded UI string on a no-op dispatch. Closing this issue rather than fixing it directly because: - The actual API bugs are the canonical root causes — fixing them is a separate workstream owned by Mark/org_mode's issue-fixer pipeline. - The UI bugs require rebuild work on ThreadCraft's combobox + state-machine, not a small patch. - Tracking these as separate issues dilutes the canonical bug list. Re-open this if the canonical API bugs (#27-#31) are fixed and the UI symptoms persist independently.
Mark closed this issue 2026-09-10 02:53:59 +00:00
Author
Owner

Reopening this issue. I previously closed it as "duplicate of #27-#31" — that was wrong.

The 3 issues in this thread (#32, #33, #34) describe client-side UI bugs in the ThreadCraft frontend that are NOT duplicates of the API-contract bugs (#27-#31) on Mark/easystitch-service. They live on different repos and represent a separate class of failure:

  • #32 (silent no-op) — Auto-Digitize button bails silently when state.uploadedImage is null. UI flow broken; user sees no error.
  • #33 (combobox swallowed) — FABRIC TYPE / STABILIZER / HOOP SIZE options render but clicking them does not update React state. Settings panel is functionally inert.
  • #34 (false-complete) — Confirm & Edit dispatches a hardcoded "Auto-digitize complete!" message without ever firing runAutoDigitize().

These bugs BLOCK the user from ever reaching the API surface that #27-#31 describe. They're prerequisite to fixing #27-#31, not duplicates of them. Closing them hides real UI bugs that need separate fixes on the ThreadCraft frontend repo (Mark/Kimi_Agent_Brother_10_Digitizing_App, not Mark/easystitch-service).

The 5 API bugs (#27-#31) remain open with the UI evidence I appended earlier. The 3 UI bugs (#32-#34) are now reopened and will be tracked independently.

The proper relationship is "blocks" (UI fixes unblock API verification), not "duplicate."

Reopening this issue. I previously closed it as "duplicate of #27-#31" — that was wrong. The 3 issues in this thread (#32, #33, #34) describe **client-side UI bugs in the ThreadCraft frontend** that are NOT duplicates of the API-contract bugs (#27-#31) on Mark/easystitch-service. They live on different repos and represent a separate class of failure: - **#32 (silent no-op)** — Auto-Digitize button bails silently when `state.uploadedImage` is null. UI flow broken; user sees no error. - **#33 (combobox swallowed)** — FABRIC TYPE / STABILIZER / HOOP SIZE options render but clicking them does not update React state. Settings panel is functionally inert. - **#34 (false-complete)** — Confirm & Edit dispatches a hardcoded "Auto-digitize complete!" message without ever firing `runAutoDigitize()`. These bugs BLOCK the user from ever reaching the API surface that #27-#31 describe. They're **prerequisite** to fixing #27-#31, not duplicates of them. Closing them hides real UI bugs that need separate fixes on the ThreadCraft frontend repo (Mark/Kimi_Agent_Brother_10_Digitizing_App, not Mark/easystitch-service). The 5 API bugs (#27-#31) remain open with the UI evidence I appended earlier. The 3 UI bugs (#32-#34) are now reopened and will be tracked independently. The proper relationship is "blocks" (UI fixes unblock API verification), not "duplicate."
Mark reopened this issue 2026-09-10 02:54:56 +00:00
Author
Owner

Final disposition: this issue has been moved to the ThreadCraft frontend repo where the bug actually lives.

  • Original location: forgejo.tail018ac4.ts.net/Mark/easystitch-service/issues/32
  • New location: forgejo.tail018ac4.ts.net/Mark/Kimi_Agent_Brother_10_Digitizing_App/issues/60

Closing this issue on easystitch-service — the fix belongs on the frontend repo. The new issue has the full body and code-path references.

Final disposition: this issue has been **moved** to the ThreadCraft frontend repo where the bug actually lives. - Original location: forgejo.tail018ac4.ts.net/Mark/easystitch-service/issues/32 - New location: forgejo.tail018ac4.ts.net/Mark/Kimi_Agent_Brother_10_Digitizing_App/issues/60 Closing this issue on easystitch-service — the fix belongs on the frontend repo. The new issue has the full body and code-path references.
Mark closed this issue 2026-09-10 02:55:19 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Mark/easystitch-service#32
No description provided.