Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

import wizard: a failed import (405, request error, failed background job, every row rejected) still shows the green check and "Import Complete" #13230

Closed

Description

@objectstack-fleet

Filing gate ① a user-visible defect with a named site and a named real producer. Follow-up owed by the landed objectui#13124 (PR #13186, ACCEPT §7). Filed by objectui domain:ui seat 1 (seat post objectui#5560, session_014MXhk1yjWh37d634hLy3p7) from a read-only census it ran to measure a finding booked on a landed card. ⛔ Not a claim.

Reader (who acts): the objectui domain:ui execution seat.

The defect

The import wizard's result step always draws a green check and "Import Complete", even when nothing was imported.

  • Site: packages/plugin-grid/src/ImportWizard.tsx:3110–:3121. result.cancelled ? <X/> + importCancelled : <CheckCircle2 className="h-10 w-10 text-green-500"/> + importComplete has no failure arm. The badges at :3127–:3138 draw "0 imported" in the primary variant.
  • Measured with the real ImportWizard (vitest and happy-dom, objectui main 5c12dcd). Every case read "Import Complete" with the green check:
    • (a) all rows created: "2 created";
    • (b) some rows failed: "1 created", "1 skipped" and a row error;
    • (c) every row failed: "0 imported", "2 skipped";
    • (d1) the import rejected with 405: "0 imported", "2 skipped", "This object is not open for import.";
    • (d2) the request throws: "0 imported", "2 skipped", "Network request failed";
    • (e) a background job ends failed: "0 imported", "Worker crashed".
  • The headline's own text is text-foreground (RESULT_HEADLINE_CLASS). The green is the icon beside it, and the dialog's accessible description reads "Import Complete" in all six cases.

reach

  • Public entry: the console object list's Import (packages/app-shell/src/views/ObjectView.tsx:4137; also ExcelImportBar.tsx:205).
  • Named real producer of (d1): objectstack answers 405 OBJECT_API_METHOD_NOT_ALLOWED for an object not open for import (objectstack#3391, handled at ImportWizard.tsx:1020–:1025).
  • Failure results reach the success arm from :2702–:2721, :2738–:2748, :2750–:2771 and :2589–:2591.

Expected

The result step says what happened:

  • a success state only when rows were imported;
  • a partial-success state when some rows were skipped;
  • a failure state (no green check, no "Import Complete") when nothing was imported or the request or job failed.

The counts and row errors stay as they are.

Dedupe

Method: semantic search_issues on objectstack-ai/objectui, open and closed.

New. Dedupe words: Import Complete failed import; import result failure state; green check 0 imported.

Activity

  1. added
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    and removed on Oct 20, 2026
  2. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 16 (priority:p3)
    Session: session_01XVp19E1MYUTFM3dnkwz8gB
    Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-13230-import-result-state
    Worktree: objectui-issue-13230
    Domain: domain:ui
    Seat: domain:ui#2
    File surface (one root cause: the result step has a cancelled arm and a success arm, and no partial or failure arm):

    • packages/plugin-grid/src/ImportWizard.tsx (the result step headline, icon and badges, ~3105–3140, plus its default-translation table);
    • packages/i18n/src/locales/*.ts: the grid.import.* rows for the new headlines, in every locale (key parity);
    • tests beside it;
    • one .changeset/13230-import-result-state.md (@object-ui/plugin-grid and @object-ui/i18n patch).

    ⛔ No change to how the result is computed, the counts or the row errors; no export moves. Stop on breach; explain in the report.
    Container & model: S, mode:subagent, model: opus (default tier; no path-derived mandate)
    Clause-②: no (internal wizard markup and new i18n rows)
    Responsibility: ImportWizard's result step draws a green check and "Import Complete" for every non-cancelled result | the result object already carries the counts and errors the step needs | every user importing into an object, including a refused (405) or failed import
    Thread-read: none
    Serial constraints cleared:


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 13230,
    "status": "done",
    "branch": "claude/issue-13230-import-result-state",
    "pr": "#13237",
    "session": "session_01XVp19E1MYUTFM3dnkwz8gB — subagent run; the parent's harness-stamped id",
    "premise_still_valid": true,
    "summary": "The ImportWizard result step now has four outcomes from a pure classifier, importResultOutcome. Success keeps the green check and 'Import Complete'. Partial (imported at least 1 and any skipped or errored row) shows 'Import finished with errors' with a neutral AlertCircle in text-muted-foreground. Failed (zero imported, or the job ended failed) shows 'Import failed' with an XCircle in text-destructive, and the '0 imported' badge uses the outline variant. Cancelled is unchanged. The headline is one DialogDescription carrying RESULT_HEADLINE_CLASS, so aria-describedby reads it in every state. New grid.import.importPartial and importFailed rows are in IMPORT_DEFAULT_TRANSLATIONS and all ten locales, and the changeset bumps plugin-grid and i18n as patch. Mechanism premise falsified: ImportResult carries no job-status or request-error field. 405 and thrown requests classify by importedRows 0. A failed job is read from finishedJob.status, which is published with the result and cleared per run. Without it, a worker that crashed after committing rows would read Partial. Ruling consequence: a deliberate ok:true 'skipped' row now reads Partial. This flipped the 13124 pin's expected headline from importComplete to importPartial; its subject, that the headline is the description, is unchanged.",
    "tests": "Head f8f81e0. New file ImportWizard.resultOutcome-13230.test.tsx plus the edited doneSubtitle-13124 file, under the lock: 'Test Files 2 passed (2) Tests 11 passed (11)', VERDICT command-exit 0. Ablation via ablation-replace.mjs, an in-source import with no dist: the anchor "if (jobStatus === 'failed' || result.importedRows <= 0) return 'failed';" was replaced with "return 'success';". Anchor went 1 to 0 and the blob c2d97a9e4e69 to ac26eaa35559. Result: (b), (c), (d1), (d2) and both (e) cases failed, while (a) and CONTROL passed: 'Tests 6 failed | 2 passed (8)'. Restore was checked by blob hash: after-restore blob == HEAD blob c2d97a9e4e69, git diff HEAD empty, and an independent git hash-object check matched. The first ablation attempt was a no-op: the tool refused because the replacement contained the anchor, and no tests ran; it was redone with a new anchor. Families under the lock, --maxWorkers=1: every plugin-grid test naming ImportWizard ('Test Files 25 passed (25) Tests 173 passed (173)'), and every i18n test naming locales or grid.import ('Test Files 60 passed (60) Tests 1075 passed (1075)'). The full packages/plugin-grid/ and packages/i18n/ directories are declared to CI. Closure build pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-grid^...' run build: exit 0. type-check for @object-ui/i18n and @object-ui/plugin-grid: exit 0, and --listFilesOnly shows both test files are in tsconfig.test.json. eslint --no-inline-config --format json on the 13 changed ts/tsx files: 13 files, 0 errors, 9 warnings, all on unchanged lines. The eslint config has no parserOptions.project, so linting is not type-aware and no untouched file's verdict can move. Battery, each exit recorded: phantom-deps, self-import, unreferenced-sources, doc-example-readers, handler-key-reads, side-effects-array, element-data-source-declaration, spec-symbols, action-forward-parity, designer-field-key-parity, icon-record-names, i18n-keys, i18n-drift, i18n-designer-parity, control-bytes, check-hand-rolled-comment-mask, check-changeset-fixed, check-changeset-presence and check:new-line-citations all exit 0. check:spec-floors exits 1 (no-artifact, unbuilt workspace; the known main state, recorded and not fixed). The control-byte self-scan of changed files found 0 hits. CI: not awaited, in_progress.",
    "mcp_calls": "0",
    "api_writes": "2 — two fleet-write relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches). The relay executed: (1) pr_create, i.e. POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos//issues/13237/assignees [baozhoutao]; (2) comment, i.e. POST /repos//issues/13230/comments (this report). Plus 2 git pushes (empty-branch probe, then commit f8f81e0), which are not REST. No labels written: objectui, and the dispatch named none.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none — noted, not filed. The wizard has no warning design token: warning surfaces (degraded notice, type-warn hint) use the raw amber palette (text-amber-600, bg-amber-50), although the console theme defines --color-warning. Polish class, not filed."
    ],
    "deviations": "Mechanism assumption in the dispatch (the result object carries the job status and the request error) is false. To honour ruling 1's 'job ended failed to Failed', the classifier also reads finishedJob.status, which is component state set alongside the result, rather than the result alone. The result's computation and shape are unchanged, and nothing new is exported. Partial uses the neutral icon because the wizard has no warning token today.",
    "files_changed": [
    "packages/plugin-grid/src/ImportWizard.tsx",
    "packages/plugin-grid/src/ImportWizard.resultOutcome-13230.test.tsx",
    "packages/plugin-grid/src/ImportWizard.doneSubtitle-13124.test.tsx",
    "packages/i18n/src/locales/{ar,de,en,es,fr,ja,ko,pt,ru,zh}.ts",
    ".changeset/13230-import-result-state.md"
    ],
    "gates": "type-check x2: 0; targeted vitest: 0; ablation: red as predicted, restored; lint (narrowed): 0; battery: 0 except spec-floors 1 (known); changeset-fixed: 0"
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    Addendum to comment 6289389404, after the PM's ruling correction. New head: a5ed3900fa on claude/issue-13230-import-result-state. The PR body is unchanged.

    • Classifier re-ruled. Only errors counts against an import. Measured signals: an ok: false row leaves an entry with its row number; a refused (405) or thrown request leaves one row-0 entry with the request message; a failed job is read from finishedJob.status. A deliberate ok: true skip leaves no entry. The four outcomes are now:
      • Failed: the job ended failed, or zero rows imported and at least one error.
      • Partial: at least one row imported and at least one error.
      • Success: everything else, including every row deliberately skipped.
      • Cancelled: unchanged.
    • The 13124 pin is reverted to base. It is byte-identical to d4d9ddbecb, and its deliberate-skip fixture reads importComplete again.
    • New pins, both Success: (f) one created plus one deliberate skip; (g) all rows deliberately skipped with none errored, and no "Import failed". (b) through (e) are kept; (c) was already built from ok: false rows.
    • Ablation: the line if (jobStatus === 'failed') return 'failed'; was replaced with return 'success'. The blob went from 03835ff85f09 to c6b55ef8afec, and the result was Tests 6 failed | 4 passed (10): (b), (c), (d1), (d2) and both (e) cases failed. Restore was checked by blob hash: the restored file matches the HEAD blob 03835ff85f09, and git diff HEAD is empty.
    • Reruns under the lock:
      • ImportWizard family: Test Files 25 passed (25) · Tests 175 passed (175).
      • i18n family: Test Files 60 passed (60) · Tests 1075 passed (1075).
      • Closure build: exit 0. type-check for i18n and plugin-grid: exit 0.
      • eslint on the 3 touched files: 0 errors (the 9 warnings are on unchanged lines).
      • i18n-keys, i18n-drift, control-bytes, unreferenced-sources, self-import, phantom-deps, comment-mask, changeset-fixed, changeset-presence and new-line-citations: all exit 0.
    • Bounds:
      • The skipped badge still uses the destructive variant for deliberate skips too, because the badges were out of this ruling's scope.
      • On the async path, if the server caps results so that no ok: false row survives, an all-error job that did not end failed would read Success. ImportResult keeps no separate error count there; skippedRows sums skipped and errored rows. This was not measured.

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #13237 @ a5ed3900fad7487f6a9be2a85171ee05d8ac88cc · domain:ui seat 2 (session_01XVp19E1MYUTFM3dnkwz8gB)

    • Clause-②: no. A module-internal classifier and two new i18n rows; no export moves, and the result's computation and shape are unchanged. No contract review is owed, and the seat read both reports.
    • Seat review: the result step reads one of four outcomes from importResultOutcome, and only result.errors count against an import. An ok: false row leaves a numbered entry. A refused (405) or thrown request leaves one row-0 entry with its message. A failed job is read from finishedJob.status. A deliberate ok: true skip leaves none.
      • Failed: the job failed, or zero imported with at least one error. Shows "Import failed", an XCircle in text-destructive, and an outline "0 imported" badge.
      • Partial: at least 1 imported with at least 1 error. Shows "Import finished with errors" with a neutral AlertCircle.
      • Success: everything else, including all rows deliberately skipped. Shows the green check and "Import Complete".
      • Cancelled: unchanged.
      • The headline is the dialog's description in every state.
    • Seat correction applied in round 2: ruling 1 had counted deliberate skips as errors. Round 2 counts errors only, and ImportWizard.doneSubtitle-13124.test.tsx is byte-identical with base again. The round-1 mechanism deviation (reading finishedJob.status beside the result) is accepted.
    • Pins: (a) all created → Success; (b) some errored → Partial; (c) every row errored, (d1) 405, (d2) thrown and (e) job failed → Failed; (f) created plus a deliberate skip → Success; (g) all deliberately skipped → Success, with no "Import failed"; CONTROL: cancelled. The ablation (the classifier returns Success) turned (b)–(e) red with (a), (f), (g) and CONTROL green, and the restore was proven by blob. The ImportWizard family (25 files, 175 tests) and the i18n family (60 files, 1075 tests) are green.
    • Changeset: @object-ui/plugin-grid and @object-ui/i18n patch.
    • CI: all 36 check-runs completed on the head, 33 passed and 3 skipped.
    • Path fork: no governed path. Seat landing.
    • Findings: Acceptance notes. (1) The skipped badge keeps the destructive variant for deliberate skips too; the badges were outside this ruling, so this is polish. (2) The wizard uses raw amber for warnings, though the theme defines --color-warning; also polish. (3) Unmeasured: on the async path, if the server caps results so that no ok: false row survives, an all-error job that did not end failed would read Success, because jobResultToImportResult folds errors into skippedRows. It is not filed until it is measured.

    Next: ready + auto-merge; landing is verified by content on main.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 2 · session_01XVp19E1MYUTFM3dnkwz8gB

    • Merged: PR fix(plugin-grid): the import result screen says what happened — success, partial or failed #13237 through the merge queue as main 7c05f210d0.
    • Verified by content: 3 of the 13 files the PR changes have the same blob at 7c05f210d0 as at the accepted head a5ed3900fa. The 10 locale packs also carry changes that landed first; in each, the PR's own hunks are identical in the merge. The merge message carries no model identifier.
    • Landed: the import result step reads one of four outcomes: Success ("Import Complete", including deliberate skips), Partial ("Import finished with errors"), Failed ("Import failed", for a 405, a thrown request, a failed job, or zero imported with errors), and Cancelled (unchanged).

    pm:dispatched is removed.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions