Skip to content

app-shell previews/flow-canvas-seeds.spec-parse.test.tsx escapes to the real network (same ECONNRESET mechanism as #4699, different file) #4701

Description

@yinlianghui

Found while verifying objectui#4699's acceptance criteria (measuring the full previews/ directory before/after that fix). #4699's own card only scoped FlowCanvas.test.tsx; a remainder from a sibling file is a new finding, not that card's.

Mechanism (same as #4699, different file)

FlowCanvas (packages/app-shell/src/views/metadata-admin/previews/FlowCanvas.tsx) calls useFlowNodePalette() → useActionDescriptors() (useFlowNodePalette.ts), which fires a real GET ${apiBase()}/automation/actions on every mount and aborts it (AbortController) on unmount. Under this repo's vitest dom project, fetch resolves to happy-dom's own polyfill — backed by Node's http/https core client (happy-dom/lib/fetch/Fetch.js: import HTTP from 'http'), not undici — so with nothing listening, the abort races a real socket and Node prints an unhandled Error: socket hang up / ECONNRESET.

packages/app-shell/src/views/metadata-admin/previews/flow-canvas-seeds.spec-parse.test.tsx renders <FlowCanvas> directly (one render() call, in describe('FlowCanvas one-click revision loop ↔ spec FlowNodeSchema (#3316)')) and has no fetch stub of its own, so it independently exercises the same escape objectui#4699 measured and fixed in FlowCanvas.test.tsx.

Measured (worktree objectui-issue-4699, on top of objectui#4699's own fix)

Isolated (pnpm exec vitest run … --maxWorkers=1):

Running the full previews/ directory (--maxWorkers=2, non-isolated) shows exactly 1 residual socket hang up line — consistent with this file being the only other one in the directory still triggering the escape (37 passed (37) files, 441 passed (441) tests).

Suggested direction

Same shape as #4699's own fix (and the #3339/#4105/#4688/#4697 family before it): stub global.fetch for the /api/v1/automation/actions endpoint in this test file too, degrading with a 404-style response so useActionDescriptors falls back to its hardcoded NODE_PALETTE — the same behavior already implicitly exercised, just without a real socket. #4699's FlowCanvas.test.tsx fix is the direct precedent to copy (a beforeEach/afterEach pair using vi.stubGlobal('fetch', …) / vi.unstubAllGlobals()).

Provenance

Measured in worktree objectui-issue-4699 (branch claude/issue-4699-flowcanvas-network-double) while verifying objectui#4699, on top of that card's own fix.


Generated by Claude Code

Activity

  1. yinlianghui commented on Aug 15, 2026

    @yinlianghui
    CollaboratorAuthor

    First-touch grading (seat repo:objectui; session session_01RnQd8iMMUwXQEV1crFmQiQ, 2026-08-15): pm:queue, size XS, tests-only — the last measured line of the network-escape hygiene family. Same mechanism and same remedy as PR #4702 (the happy-dom http-core fetch on /api/v1/automation/actions), one sibling file (flow-canvas-seeds.spec-parse.test.tsx, 1 line isolated). Rides with any future dev touching that directory, or as a standalone XS when a slot is idle; acceptance = that file isolated shows 0 noise lines with its 25 assertions unchanged. Sequenced after PR #4702 lands.


    Generated by Claude Code

  2. self-assigned this
    on Aug 15, 2026
  3. yinlianghui commented on Aug 15, 2026

    @yinlianghui
    CollaboratorAuthor

    Claim: PM loop round 12 (sequencing cleared — PR #4702 is MERGED)
    Session: session_01RnQd8iMMUwXQEV1crFmQiQ
    Branch: claude/issue-4701-flowcanvas-seeds-double
    Worktree: objectui-issue-4701
    Domain: repo:objectui
    File surface: packages/app-shell/src/views/metadata-admin/previews/flow-canvas-seeds.spec-parse.test.tsx + tests-only empty-frontmatter changeset if the presence gate demands one. ⛔ No production source; ⛔ no skip-changeset label — the empty-frontmatter changeset is the mechanism (stop on breach; explain in the report)
    Container & model: XS, mode:subagent, model: sonnet
    Serial constraints cleared: in-flight is objectstack#8830 (other repo) and #4487 (plugin-dashboard tests — disjoint); no open dev PR touches this file.


    Generated by Claude Code

  4. yinlianghui commented on Aug 15, 2026

    @yinlianghui
    CollaboratorAuthor

    <!-- os-dev-report -->

    {
      "issue": 4701,
      "status": "done",
      "branch": "claude/issue-4701-flowcanvas-seeds-double",
      "pr": "https://github.com/objectstack-ai/objectui/pull/4703",
      "premise_still_valid": true,
      "summary": "Confirmed the premise (baseline isolated run showed the 1 socket-hang-up line, 25/25 tests passing) and installed the same beforeEach/afterEach vi.stubGlobal('fetch', ...) pair PR #4702 used for FlowCanvas.test.tsx, in flow-canvas-seeds.spec-parse.test.tsx, stubbing /api/v1/automation/actions with a 404 so useActionDescriptors falls back to NODE_PALETTE instead of racing a real socket. Tests-only change plus an empty-frontmatter changeset (app-shell is in the fixed release group); no production source touched.",
      "tests": "At final HEAD ec8773f3a: isolated run of flow-canvas-seeds.spec-parse.test.tsx (--maxWorkers=1) -- baseline showed 'Error: socket hang up' / ECONNRESET plus 'Test Files 1 passed (1), Tests 25 passed (25)'; post-fix shows 0 noise lines with the same 25 passed (25). Full previews/ directory (--maxWorkers=2): 37 files / 441 tests passed, 0 socket-hang-up lines total (previously 1 residual line). Reverse verification: committed the fix, reverted the stub via git checkout against HEAD~1, isolated run reproduced the 1-line noise with tests still green (25 passed), then restored the fix and re-ran green with 0 noise. Additional gates at HEAD ec8773f3a: eslint --quiet on the file (clean), pnpm --filter @object-ui/app-shell run type-check with the dependency closure built first via pnpm --filter '@object-ui/app-shell^...' build (clean), node scripts/check-changeset-presence.mjs (green, declares .changeset/flowcanvas-seeds-network-double.md with empty frontmatter), pnpm run check:control-bytes (clean). No scripts/pm/dispatch-gates.mjs exists in this repo (objectui, not objectstack) so the named gate list from the dispatch prompt is what applied.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  5. yinlianghui commented on Aug 15, 2026

    @yinlianghui
    CollaboratorAuthor

    (Correction of comment 5302164139 above, which accidentally posted the marker HTML-entity-escaped as &lt;!-- os-dev-report --&gt; instead of literal <!-- os-dev-report --> -- this comment carries the real marker; the JSON payload is identical.)

    {
      "issue": 4701,
      "status": "done",
      "branch": "claude/issue-4701-flowcanvas-seeds-double",
      "pr": "https://github.com/objectstack-ai/objectui/pull/4703",
      "premise_still_valid": true,
      "summary": "Confirmed the premise (baseline isolated run showed the 1 socket-hang-up line, 25/25 tests passing) and installed the same beforeEach/afterEach vi.stubGlobal('fetch', ...) pair PR #4702 used for FlowCanvas.test.tsx, in flow-canvas-seeds.spec-parse.test.tsx, stubbing /api/v1/automation/actions with a 404 so useActionDescriptors falls back to NODE_PALETTE instead of racing a real socket. Tests-only change plus an empty-frontmatter changeset (app-shell is in the fixed release group); no production source touched.",
      "tests": "At final HEAD ec8773f3a: isolated run of flow-canvas-seeds.spec-parse.test.tsx (--maxWorkers=1) -- baseline showed 'Error: socket hang up' / ECONNRESET plus 'Test Files 1 passed (1), Tests 25 passed (25)'; post-fix shows 0 noise lines with the same 25 passed (25). Full previews/ directory (--maxWorkers=2): 37 files / 441 tests passed, 0 socket-hang-up lines total (previously 1 residual line). Reverse verification: committed the fix, reverted the stub via git checkout against HEAD~1, isolated run reproduced the 1-line noise with tests still green (25 passed), then restored the fix and re-ran green with 0 noise. Additional gates at HEAD ec8773f3a: eslint --quiet on the file (clean), pnpm --filter @object-ui/app-shell run type-check with the dependency closure built first via pnpm --filter '@object-ui/app-shell^...' build (clean), node scripts/check-changeset-presence.mjs (green, declares .changeset/flowcanvas-seeds-network-double.md with empty frontmatter), pnpm run check:control-bytes (clean). No scripts/pm/dispatch-gates.mjs exists in this repo (objectui, not objectstack) so the named gate list from the dispatch prompt is what applied.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  6. yinlianghui commented on Aug 15, 2026

    @yinlianghui
    CollaboratorAuthor

    ACCEPT — PR #4703 (reviewer of record; readings taken on GitHub at head ec8773f3a, matching the report's gate-union HEAD).

    CI converging — ready + auto-merge flips when gates conclude (timer armed). Card closes on merge; pm:dispatched comes off then.


    Generated by Claude Code

  7. added a commit that references this issue on Aug 17, 2026
    9729236
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions