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

Closed
opened 2026-09-10 02:55:18 +00:00 by Mark · 1 comment
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.


Moved from Mark/easystitch-service#32 — these are UI bugs in the ThreadCraft frontend, not API bugs on the easystitch-service. They were originally filed on the wrong repo because both projects are part of the same ThreadCraft shakedown work, but the fix surface is here.

Original issue #32 retained as a cross-reference.

**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. --- **Moved from Mark/easystitch-service#32** — these are UI bugs in the ThreadCraft frontend, not API bugs on the easystitch-service. They were originally filed on the wrong repo because both projects are part of the same ThreadCraft shakedown work, but the fix surface is here. Original issue #32 retained as a cross-reference.
Author
Owner

Fixed by commit 8a8cb8b (pushed via merge fe4a509). The inner 'Run Auto-Digitize' button now calls runAutoDigitize directly instead of dispatching a sentinel state and relying on a stale-closure useEffect. A re-entry guard inside runAutoDigitize prevents duplicate POSTs. Regression test: src/components/workspace/issue-60.test.tsx (renamed to repro-60.test.tsx). Verify gate (6/6 commands) passed: useWorkspace + CanvasArea + RightPanel + repro-60 vitest, pnpm lint, tsc -b.

Fixed by commit [8a8cb8b](https://forgejo.tail018ac4.ts.net/Mark/Kimi_Agent_Brother_10_Digitizing_App/commit/8a8cb8b) (pushed via merge [fe4a509](https://forgejo.tail018ac4.ts.net/Mark/Kimi_Agent_Brother_10_Digitizing_App/commit/fe4a509)). The inner 'Run Auto-Digitize' button now calls runAutoDigitize directly instead of dispatching a sentinel state and relying on a stale-closure useEffect. A re-entry guard inside runAutoDigitize prevents duplicate POSTs. Regression test: src/components/workspace/issue-60.test.tsx (renamed to repro-60.test.tsx). Verify gate (6/6 commands) passed: useWorkspace + CanvasArea + RightPanel + repro-60 vitest, pnpm lint, tsc -b.
Mark closed this issue 2026-09-13 01:26:10 +00:00
Sign in to join this conversation.
No description provided.