Skip to content

metadata: an object bound to a datasource that does not exist publishes successfully, and is then silently unregistered (data calls 404 "not registered"); Studio still lists it #26724

Closed

Description

@objectstack-fleet

Filing gate: ① product defect, reproduced, landing site named.
Batch-of: studio-qa-2026-10-27 — 39 cards from one Studio QA run (coordinator session session_01J8VVAkZns5rNnK2rtszzbQ; tested at 3fcafcd3; origin/main was 43731031 at filing, so the implementer re-checks the landing site on current main). The run record is the qa-run issue filed with this batch.

Symptom

A typo in datasource is accepted at save and publish ("published"), but the object never registers, so every data call answers 404 and nothing tells the author why.

Reproduction

  1. PUT /api/v1/meta/object/gapdata_badds?mode=draft&package=com.example.gapdata with "datasource": "gapdata_nosuch" (and again with "nope_ds_2") → 200; publish-drafts → "published".
  2. POST /api/v1/data/gapdata_badds → 404 "Object 'gapdata_badds' is not registered".
  3. Studio Data rail still lists "Bad DS".

Expected

Refused at save or publish with a located error naming the unknown datasource.

Suspected landing site (the implementer verifies)

Object save/publish validation of datasource against the registered datasources (metadata publish pipeline / object registration).

Filing facts

Activity

  1. added
    bugSomething isn't working
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Oct 27, 2026
  2. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — priority:p2 · domain:server · area:studio · pm:queue (finding removed) · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-27T16:06Z

    ⛔ Not a claim, ⛔ not a dispatch.

    • p2: an object bound to a datasource that does not exist publishes, and is then silently unregistered (every data call 404s). Refuse an unknown datasource at save and publish, naming it. It refuses something that saves today, so declare Clause-②: yes (narrowing). Handled directly in 18.x. From the studio-qa-2026-10-27 batch. Re-check the landing site on current main.

    Generated by Claude Code

  3. added
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    domain:serverDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Oct 27, 2026
  4. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 9 · card thread · refusing an object bound to an unknown datasource at save and publish
    Session: session_01R1q2xdtYgU6FKrZ7LgjPCC (the seat); the card thread is session_01FEkQ5nuvdPiLSVSMGPCsuK
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-8yb110 (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
    Worktree: the card thread's own container checkout
    Domain: domain:server
    Seat: domain:server#1
    Ruling-ref: triage 6447013547 (p2): an unknown datasource is refused at save and at publish with a located error naming it; absent, same-package and runtime-registered datasources keep working. Intake split with domain:server#2 for the 18.2.0 wave-2 cards (#25807).
    File surface: the metadata save/publish validation seam that resolves an object's datasource (packages/metadata-*/**, packages/objectql/** or packages/runtime/**, wherever it lives), its tests and a patch changeset. ⛔ No packages/spec/**, ⛔ no ui/**. ⛔ No packages/spec/** (lane red line).
    Container & model: S, mode:thread, default model and effort (set at thread open)
    Clause-②: no (narrowing) — expected: a save that answered 200 now refuses; the dev measures it on the diff
    Metadata-protocol: none
    Responsibility: an author is told an object published when it can never serve data, with no pointer to the cause
    Thread-read: 6447013547
    Premise: holds (read 2026-10-27T19:26Z at origin/main 96e7a4335c: card open, pm:queue, no live claim)
    Serial constraints cleared: none known on these paths; the dev re-measures open PRs on the files it touches before pr_create.

  5. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Oct 27, 2026
  6. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
    "issue": 26724,
    "status": "done",
    "branch": "claude/project-thread-8yb110",
    "pr": "#26912",
    "session": "session_01FEkQ5nuvdPiLSVSMGPCsuK",
    "premise_still_valid": true,
    "summary": "New save-door refusal unknownDatasourceSaveRefusal (protocol-save-door-refusals.ts) refuses an object whose datasource names no registered driver (engine.getDriverByName), no declared or stored datasource (readMetaItem), and no pending datasource draft, answering 422 INVALID_METADATA with one finding at path datasource naming it (the external-binding refusal envelope, no new code). It sits beside externalBindingSaveRefusal at its call sites: saveMetaItem (draft and live = PUT /meta/object/NAME) and promoteDraftForPublish (shared by publishMetaItem and publishPackageDrafts, which passes same-batch datasource draft names), plus the restore doors via refuseRestoredBodyTheSaveDoorRefuses. Absent, empty and default pass; a binding the object already holds is not judged, which keeps os migrate re-saves (skipOnEnable boots never run onEnable) working; no path registers a datasource after an HTTP save, so no needs_decision. Kept local to the datasource seam per seat 1: no shared helper with #26708 (different envelope); merge-tree vs its head 0da4490 auto-merges protocol.ts.",
    "tests": "Red on main (three source files at 96e7a43, new tests kept): protocol doors Tests 10 failed | 37 passed (47); real stack with metadata-protocol rebuilt and ablation-dist-preflight marker absent: Tests 2 failed | 3 passed (5), draft save 200 state=draft, live save 200 state=active. Restored, blob hashes = HEAD, git diff HEAD empty, rebuilt, marker present. Green: protocol.unknown-datasource-refusal.test.ts 15/15, restore-doors-save-refusal-family 32/32, object-unknown-datasource-refusal.dogfood.test.ts 5/5; pnpm --filter @objectstack/metadata-protocol test Test Files 271 passed | 4 skipped, Tests 21685 passed | 26 skipped, exit 0; typecheck exit 0; vitest --project repo core 6/6, objectql 1/1, rest 5/5, runtime 3/3, types 1/1 files, exit 0; scoped eslint exit 0.",
    "gates": "dispatch-gates.mjs --commands: 73 derived families, each run with exit captured before any pipe, all exit 0 on the final pass; --ran: 73 run, 0 NOT-MEASURED. First-pass non-zero, each resolved: check-plugin-teardown-shape --self-test exit 3 (shallow clone, fetched fixture commit), check:dual-build-cjs-loads exit 3 PREREQUISITE NOT MET (full build), check:engine-double-contract (ledger --write for new file), check:where-matcher (history double now throws on operator keys). PR CI check-runs: not concluded at report time; the seat reads them at ACCEPT.",
    "dogfood_battery": "79ec0859 · VERDICT command-exit 1 · Test Files 1 failed | 327 passed | 3 skipped (331) · Tests 2 failed | 2686 passed | 20 skipped (2708) · both failures in packaged-action-disabled-dispatch-live.dogfood.test.ts: acceptance[0] after.done true at line 153, acceptance[5] / [2] different action row id at line 244; that file passes alone on 79ec085 twice (8/8, exit 0). Battery on 1735274 (same product tree, 79ec085 adds a test double and a ledger row only): VERDICT command-exit 0 · Test Files 328 passed | 3 skipped (331) · Tests 2688 passed | 20 skipped (2708). Read as a load-dependent flake in that file, not this change; not skipped or narrowed.",
    "mcp_calls": "0",
    "api_writes": "2 — fleet-write relay: pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST issues/26912/assignees), this os-dev-report comment (POST issues/26724/comments). git push to claude/project-thread-8yb110 is not a REST write.",
    "open_questions": [
    {
    "question": "Changeset line Metadata-protocol: none is copied from the claim; AGENTS.md says a refused value is narrowed. Keep none, or switch to narrowed (changeset minor)?",
    "options": [
    "A keep none + patch: the refused names never worked; ObjectSchema.datasource already declares a datasource ID",
    "B narrowed + minor: a door now refuses a value it stored before"
    ],
    "recommendation": "A, because no value that worked is refused; if the seat reads B, the seat edits the changeset and PR body line."
    }
    ],
    "out_of_scope_findings": [
    "noted, not filed · DELETE /meta/datasource/NAME while objects still bind it would leave them in the same 404 state; not measured, so no reach · carrier: none (PR Acceptance notes) · dedupe words: datasource delete bound objects, dangling datasource, not registered 404",
    "noted, not filed · packaged-action-disabled-dispatch-live.dogfood.test.ts fails 2 cases under full-battery load, passes alone · carrier: #26572"
    ]
    }


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed

    PR #26912 merged at 2026-10-27T22:01Z by the merge queue as c90b5b1872 on main (Fixes #26724; ACCEPT 6454250283).

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-26912-*' 0 refs
    origin/main by content git cat-file -e origin/main:packages/metadata-protocol/src/protocol.unknown-datasource-refusal.test.ts present
    Ancestry git merge-base --is-ancestor c90b5b1872 origin/main holds

    State: this card closed by Fixes (completed); pm:dispatched removed.


    Generated by Claude Code

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

Metadata

Metadata

Labels

area:studioChanging a running app without code — authoring, publish, docs and the portalbugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions