Repository navigation
fix(app-shell): a refused package publish names each refused item with the server's reason (objectui#11922) - #11983
Merged
objectstack-fleet[bot] merged 1 commit intoOct 8, 2026
Conversation
…h the server's reason The package sheet's publishDrafts and usePublishAllDrafts (Home's Publish all, the draft-preview bar) read the batch's own success === false before failed[]. A refusal carries both, so the author read "Action failed" or "publish-drafts did not publish this package". Both now read failed[] first and name the refused items (the causal item on a rollback, every item on a pre-flight refusal) through one module-private helper, preview/publishRefusal.ts. Claude-Session: https://claude.ai/code/session_01MgfduSkFrfM3eorB3UGfAU Co-authored-by: Claude <noreply@anthropic.com>
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
objectstack-fleet
Bot
deleted the
claude/issue-11922-publish-refusal-reason
branch
October 8, 2026 15:46
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #11922
Clause-②: no
What changes
A refused
POST /packages/:id/publish-draftsbatch now names each refused item with the server's reason at the two doors outside Studio.PackagesPage,publishDrafts).failed[]is read before the batch's ownsuccess === false. A rolled-back batch keeps thepublishDraftsRolledBackrow and names its causal item. A refusal with noBATCH_ABORTEDelement (the runtime's pre-flight checks) keeps thepublishDraftsPartialrow and names every refused item after it. The envelope ladder (readEnvelopeFailureText, then "Action failed") now runs only whenfailed[]is empty.usePublishAllDrafts). A non-emptyfailed[]throws the refused items' text before thesuccess === falsecheck, so the toast reads "Publish failed: object/lead: REASON" instead of "Publish failed: publish-drafts did not publish this package".packages/app-shell/src/preview/publishRefusal.ts(refusedItemsText), not exported from the package entry. It names every element that is not aBATCH_ABORTEDsibling astype/name: error, joined with;. If every element is aborted, it names the first one.No export, prop, type member, spec key or language-pack key is added. The wording is the existing rows plus the server's own
errortext.The producer's shape (H1), read at objectstack
51290bcaIn
packages/metadata-protocol/src/protocol.ts,publishPackageDrafts, quoted by content:success: false,outcome: 'refused',publishedCount: 0, andfailed: preflightViolations.map((v) => ({ type: v.type, name: v.name, error: v.error, code: v.code })). The codes areNAMESPACE_PREFIXandSTORED_TYPE_NOT_CANONICAL, and no element isBATCH_ABORTED.success: falseandoutcome: failedOut.length > 0 ? 'refused' : 'nothing_to_publish'. The causal item carrieserror: clientFacingFailureText(e, 'publish failed'), plus itscodeandissueswhen the cause has them. Every sibling carriescode: 'BATCH_ABORTED'and anerrorthat names the causal item.errorkey on either return. That is why the old ordering fell to the ladder's last rung, "Action failed".packages/runtime/src/domains/packages.tsanswers the route withdeps.success(result), so the wire is{ success: true, data: BATCH }on a 200.MetadataClient.publishPackageDraftsunwrapsdata, so both doors read the batch's ownsuccess. The spec states the invariant onPublishPackageDraftsResponseSchema.outcome: "refusedif and only iffailed.length > 0".Why not
formatPublishFailuresThe seat's call was to reuse
formatPublishFailuresandPublishFailurefromstudio-design/metadataError.ts, unless measurement showed new eager bytes or a shape that does not fit. Measured: the shape does not fit.formatPublishFailuresthe producer's rollback shape: a causalobject/leadand twoBATCH_ABORTEDsiblings. It printed three parallel lines (the causal item, then each sibling's "not published — the batch is all-or-nothing …") and no rolled-back banner.f.code === BATCH_ABORTED_CODE, andBATCH_ABORTED_CODEis'batch_aborted', the pre-ADR-0112 spelling.The helper here uses
errorCodeIs, which matches both spellings. The eager-bytes half was not measured locally, because no full console build was run. The budget bot's reading on this PR is that measurement.metadataError.tsis not edited, because another seat's work touches it. Its casing defect is listed under Acceptance notes.Tests (HEAD
6226e589d)New tests.
PackagesPage.publishRefusal-11922.test.tsx(4 cases) andpreview/__tests__/usePublishAllDrafts.refusal-11922.test.tsx(3 cases). Each drives the realuseMetadataClientand client. Onlyfetchis stubbed, plussonnerfor the hook.Targeted vitest run. One repo-root
pnpm exec vitest runcovered:PackagesPageorusePublishAllDrafts;useMetadataClient.advisorySink.test.tsx;perm-home-namespace-3546.test.tsx, which readsusePublishAllDrafts.ts's source;StudioDesignSurface.publishCount-11807.test.tsxandmetadataError.test.ts;column-identity.ratchet.test.ts.Result:
Test Files 26 passed (26),Tests 214 passed (214). The 26 includes the uncommitted scratch measurement file.Type-check.
pnpm --filter @object-ui/app-shell type-check: exit 0. The dependency closure came from the turbo cache.tsc -p tsconfig.test.json --listFilesOnlylists both new test files and the helper.scripts/__tests__/one-authority-per-exported-name-6273.test.ts, under the lock:Tests 11 passed (11). The helper exports one function,refusedItemsText, and no other module exports that name. Its parameter type stays unexported.ESLint on the five touched files: 0 errors. All 20 warnings sit on lines this PR does not touch.
Gates, all exit 0:
node scripts/check-changeset-presence.mjs,node scripts/check-changeset-no-major.mjs,pnpm check:new-line-citations(0 new citations),check:control-bytes,check:i18n-keys,check:vi-mock-specifiers,check:vi-mock-inherit,check:vi-mock-override-shape,check:test-path-roots,check:unreferenced-sources,check:changeset-claimsandcheck:pending-changeset-literals.Ablation (HEAD
6226e589d, fix committed first)The old ordering was put back with
ablation-replace.mjs. Each anchor hit once and went from 1 to 0, and each blob changed.if ((r as { success?: boolean }).success === false) {.failed[]throw was deleted.Result:
Tests 4 failed | 4 passed (8).Received: "home.pendingDrafts.publishFailed: publish-drafts did not publish this package".publishDraftsOk;errorwith an emptyfailed[]shows the envelope's text;success: false, so the old ordering never reached thepublishDraftsRolledBackrow. It is a new pin, not a control.ablation-replace.mjs --restoreran on both paths. Each blob equals its HEAD blob (ade4d2874,b84739516), andgit diff HEADis empty.Acceptance notes
formatPublishFailuresinstudio-design/metadataError.tstells a rolled-back sibling apart by'batch_aborted'compared with===, but the producer emitsBATCH_ABORTED.StudioDesignSurface, after objectui#11916) andAiChatPagetherefore list every aborted sibling as a parallel error and never show the rolled-back banner (measured above).spec:PublishPackageDraftsResponseSchema.failed[].code(SCREAMING_SNAKE) →renderer:formatPublishFailures. Handed to the seat for filing.outcome: 'nothing_to_publish'(success: false, emptyfailed[]) as a failure, where Studio says "nothing to publish" (objectui#11807). Reaching it needs drafts that were listed but are no longer pending at publish time, and that was not measured at either door. This PR keeps that path unchanged; it is the H2 envelope control.DraftChangesPanelsays the metadata-admin string table is not on the console's eager graph.services/builtinComponents.tsximportsPackagesPagestatically, andPackagesPageimports that table. This was read from source only; the budget bot is the measurement.Generated by Claude Code