Skip to content

A publish failure's error string inlines the same validation prose that issues[] already carries, so every console renders each finding twice #10524

Description

@os-support-ai

Filed from objectstack-ai/objectui#5418 (Studio dogfood, 17.1.0). Filed here, not in objectui, because the fix is producer-side: de-duplicating in the consumer is the alias-tolerance shape Prime Directive #12 forbids, so objectui deliberately did not touch it.

Measured

The publish-drafts response's failed[] entries carry both:

  • error — a summary string that already contains the rendered issue text, and
  • issues[] — the same findings, structured ({ path, message }).

objectui's formatPublishFailures renders ${type}/${name}: ${error} and then one • path — message line per issue, which is the right thing to do with that contract — it is what turns an opaque banner into a field-anchored list. The result on the card's walk was the same sentence twice:

object/crmext_visit: [invalid_metadata] object/crmext_visit failed author-time validation:
objects[71].sharingModel: [security-owd-unset] custom object "crmext_visit" declares no
sharingModel (OWD). The runtime fails CLOSED to 'private' (ADR-0090 D1), but the baseline
must be an authored decision, not an accident — this is the exact shape of the leave_request
incident (objectstack-ai/objectui#2348). • objects[71].sharingModel — custom object "crmext_visit" declares
no sharingModel (OWD). …

The original reporter called this out directly: "a wall of English ADR prose (the same sentence twice, once as a summary and once as a bullet)".

Why the consumer must not fix it

Every plausible client-side fix is a guess about producer text — strip the summary when issues.length > 0 (loses the summary's own framing for non-validation failures), or substring-match the issue text out of error (a parser for prose). Both are exactly the consumer tolerance that hides producer drift.

Suggested shape

error should be the headline — what failed and why, one sentence — with the per-path detail left to issues[], which is the structured channel that exists for it. Consumers that render only error (logs, CLI) keep a usable message; consumers that render both stop repeating themselves.

Confidence / what I did NOT measure

The duplication is read off the reporter's captured console output plus objectui's formatter, which I did read. I did not run a live publish against a framework build to confirm which server-side site composes error — worth confirming before choosing where the change lands.

Related

Activity

  1. added theissue type on Aug 21, 2026
  2. os-zhuang commented on Aug 21, 2026

    @os-zhuang
    Contributor

    Triage: producer-side fix (the publish-drafts failed[] composer, framework side) → domain:engine, pm:queue, type Task. The consumer-side non-fix is already ruled posture (alias-tolerance forbidden), so the only landing site is where error is composed.

    Dispatch notes, premise-first: the filer did not confirm which server-side site composes error — the dev's first step is locating it (likely the metadata publish path that builds failed[] entries; verify, don't inherit). Target shape as suggested: error = one-sentence headline, per-path detail stays in issues[]. Check consumers that render only error (CLI, logs) keep a usable message — that is the acceptance criterion, not string equality with today. Relation: #10462 (open decision card on publishPackageDrafts success:false semantics) touches the same response contract — if its ruling lands first, re-read this card's shape against it; do not pre-empt that ruling here.

    Size/model suggestion: S–M, mode:subagent, opus.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions