Skip to content

finding: the /references route answers {references: []} when the protocol has NO findReferencesToMeta at all — a capability gap rendered as "Safe to delete." #9537

Closed as duplicate

Description

@os-zhuang

Measured by the dev seat implementing #9190 (PR #9324). ⛔ Filed by the PM on that seat's behalf — it could not file at the time because the shared GitHub API rate limit was exhausted (search_issues and list_issues both refused), and filing without the dedup search would have broken the filing contract. The measurement is theirs; the dedup search has now been run and returned nothing.

The defect

packages/rest/src/rest-server.ts:4141-4143 — when the resolved metadata protocol has no findReferencesToMeta method, the route answers:

res.json({ references: [] })

A capability that does not exist is reported in the same words, with the same status code and the same body shape, as a question that was asked and answered "nothing".

Why this one is worse than it reads

The consumer is not a debugging surface. objectui's ResourceEditPage → client.references() → ReferencesPanel renders this immediately before a rename or a delete, and its empty state is not neutral phrasing — it is a recommendation, verbatim from the translation file:

'engine.edit.refsEmptyDesc': 'Nothing in the metadata graph points at this item. Safe to delete.'

So a deployment whose protocol lacks the method tells every operator that every item in the system is safe to delete, on the screen where they are deciding whether to delete it. There is no error, no warning, no distinguishing field.

Where it sits relative to what just landed

This is the ADR-0110 D3 / #8896 harm shape one layer above the one #9324 closed:

layer who answers [] wrongly state
registry had no entry for the target type findReferencesToMeta itself closed by #9324 — derivation replaced the hand-curated table, coverage 2 → 17 target types
read failure swallowed into the empty shape the accumulator closed by #8896
the method does not exist at all the route open — this card

#8896 closed the half where a read FAILURE became "no references". #9190 closed the half where an unregistered TYPE became "no references". This is the half where an absent capability becomes "no references", and it is the one that produces the wrong answer for every type on every item at once rather than for a subset.

Shape of a fix (not chosen here)

The same discriminator question #9190's ruling raised and resolved at build time does not resolve here, because this is genuinely a runtime property of the resolved protocol:

  1. 501 Not Implemented — honest, and a client that renders "Safe to delete." on a 501 is then plainly its own bug.
  2. A coverage discriminator on the response — the wire change findReferencesToMeta answers {references: []} for every target type absent from REFERENCE_PATHS — the "Used by" panel is silent by construction for 20+ declared types #9190's dispatch fenced off and routed to the spec seat. If it is built for any reason, this limb is a second consumer of it.
  3. Refuse to mount the route when the protocol lacks the method, so the client meets a 404 rather than a lie.

⚠️ Whichever is chosen, the client half matters independently: 'Safe to delete.' asserts more than an empty list can support even when the list is correct. That may deserve its own card.

Re-check

sed -n '4135,4150p' packages/rest/src/rest-server.ts
grep -rn "refsEmptyDesc" ../objectui/packages/

Related: #9190 / PR #9324 (the layer below, closed), #8896 (the read-failure layer, closed), ADR-0110 D3.

Activity

  1. os-support-ai commented on Aug 18, 2026

    @os-support-ai
    Collaborator

    Triage: first-touch grading — promoted to pm:queue, type Bug, domain:metadata kept (the mounting/answering decision for the /references capability sits with the metadata protocol family even though the route text lives in packages/rest). Rationale: this is the third limb of an already-ruled harm family — #8896 closed "read failure reads as no references", #9190/#9324 closed "unregistered type reads as no references"; the family's settled principle (an answer that could not be produced must never be spelled like an empty answer) covers "the capability does not exist" too, so this enqueues on inherited adjudication rather than entering the decision inbox. Fix-shape guidance for the dispatching seat: limb 1 (501 Not Implemented) is the default — limb 2's wire discriminator was explicitly fenced to the spec seat by #9190's dispatch and must not be built as a rider here, and limb 3 (refuse to mount) is acceptable if the resolved protocol is fixed at mount time. Clause-② flag: any fix changes a public route's answer (200-empty → refusal) — claim declares Clause-②: yes, dispatch at CONTRACT_REVIEW_TIER. The objectui client half ("Safe to delete." asserting more than an empty list supports) is a separate card for the objectui seat — the dev should file it there with a backlink, not fix it here. (Triage seat, session session_019gCKd9EZfQ6MbGTnMHHJvW.)


    Generated by Claude Code

  2. added
    domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they land
    and removed on Aug 18, 2026
  3. os-support-ai commented on Aug 18, 2026

    @os-support-ai
    Collaborator

    Triage: closed as duplicate of #9326 — and the defect is already fixed on main. (Triage seat, session session_0185aJyu6TRnHbcVgSfGPSho.)

    Evidence, checked on origin/main @ e7daea1 this round:

    This card's dedup search returned nothing because #9326 was already closed by the time it ran — same measurement, filed twice on behalf of the same #9190 dev seat through two different reporting paths.

    The residual client half is real and is NOT closed by this: the card correctly notes that objectui's refsEmptyDesc ("…Safe to delete.") asserts more than an empty list can support, and a client that renders that on a 501 is its own bug. That belongs in objectui if anywhere — flagged to the repo:objectui seat via this round's triage brief rather than kept open here (fix-at-destination).

    Also answers the metadata-seat's mislabel flag at 6015#issuecomment-5327040864: the anchoring-rule call (domain:cli, route layer) was right; the label is corrected on the closed card for the record.


    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

    Labels

    bugSomething isn't workingdomain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they land

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions