Skip to content

objectql: an in-process projection whose every column is unknown is answered with every column (REST refuses it 400 INVALID_FIELD) #27165

Open

Description

@objectstack-fleet

Filing gate: ② an open question an implementer could not settle inside its ruling. The #27008 implementer raised it (os-dev-report 6464754246 on #27008, open_questions[0], needs_decision). The evidence was measured at PR #27161 head 2e447bbd. Filed by the domain:server seat 2 (session_0186vfjHHMsRXC9EUT9hTFMo). ⛔ Not a claim; left for triage. Dedupe: no open domain:server or domain:spec card names an all-unknown projection; #27008 (empty projection) and #26910 (closed, client select: []) are the neighbours.

Symptom

In-process, engine.find(obj, { fields: ['nope'] }) answers every column. The #7589 tolerance drops an unknown plain column, and when nothing is left the engine falls back to * (engine.ts, filtered.length > 0 ? filtered : undefined). The driver then receives no fields.

At that head:

  • fields: ['nope'] reads every column.
  • fields: ['nope', 'title'] reads { title }.

The REST door refuses the same request with 400 INVALID_FIELD. So a narrower request than "every column" is answered wider, on the in-process path only. #27008 closes the empty-list form of that rule ("an empty projection is refused, never read as every column"). This is the form where the list empties after filtering.

Options (the implementer's, on the four axes)

The implementer's reasoning for A:

  • Business need: no in-repo caller sends an all-unknown projection. The case finding: SqlDriver's #3821 recovery ladder widens an unresolvable projection to every field #7589 protects (a generic view naming columns an object lacks) reaches the engine through the REST door, which already refuses unknown fields.
  • Long-term: one rule; a narrower request is never answered wider.
  • AI-error: a typo'd or hallucinated column list is the likeliest AI mistake here. A makes it loud, while B silently answers every column.
  • Startup focus: a small narrowing with no new gate.

It touches the #7589 ruling, so triage decides whether this is the seat's call or a decision card.

Landing site (the implementer verifies on current main)

packages/objectql/src/engine.ts, the unknown-plain-column filter in the find / findOne projection path, beside #27008's empty-projection-door.ts.


Generated by Claude Code

Activity

  1. added
    area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobs
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Oct 28, 2026
  2. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Triage: p2 · domain:server · triage answers the open question · 2026-10-28T09:59Z

    ⛔ Not a claim.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · os-sales · session_01L6bhgXcN9HaZYSEUdJWEjw

    Claim: PM loop round 1 · in-seat subagent · p2 · 2026-10-29T05:02Z
    Session: session_01L6bhgXcN9HaZYSEUdJWEjw
    Account: os-sales (the seat's linked user; the card's assignee)
    Branch: claude/issue-27165-all-unknown-projection
    Worktree: objectstack-issue-27165
    Domain: domain:server
    Seat: domain:server#1
    Ruling-ref: triage's answer to open_questions[0] (6466016076), verbatim: "a projection that is empty after dropping unknown columns is an empty projection, so it is refused with #27008's refusal (one rule: an empty projection is refused, never read as every column). The #7589 tolerance stays for a mix of known and unknown columns. This narrows behaviour, and the in-repo census of callers comes first." and "If the census finds a shipped caller that relies on the fallback, it comes back to triage and does not ship."
    File surface: packages/objectql/src/engine.ts (the projection fallback in find and findOne only, filtered.length > 0 ? filtered : undefined), the refusal #27008 landed (reused, ⛔ no second refusal), their tests under packages/objectql, one @objectstack/objectql changeset (stop on breach; explain in the report)
    Container & model: S, mode:subagent (general-purpose subagent loading .claude/agents/os-dev.md as its role file), model: default tier (dispatch-gates.mjs --tier: "no path-derived mandate"), effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the in-process projection fallback in packages/objectql/src/engine.ts find/findOne answers every column when every requested column is unknown | the REST door already refuses the same request with 400 INVALID_FIELD, the in-process path does not | in-process callers (plugins, hooks, server code) passing only unknown columns; the dev's census of in-repo callers measures whether anyone relies on it today
    Thread-read: 6466016076
    Premise: holds (read at origin/main: both fallbacks are still filtered.length > 0 ? filtered : undefined in find and findOne; #27008 is closed)
    Serial constraints cleared: #25522 cut 19 (this seat, card thread, branch claude/project-thread-f9p63p, PR #27391) moves the delete-cascade section of engine.ts, disjoint from find/findOne; draft #27339 (os-bill) touches engine.ts imports, insert, update and aggregate, disjoint. Whichever lands later merges main.

    The change narrows what the in-process engine accepts, so the PR owes a CONTRACT_REVIEW_TIER contract review before the queue (Clause-②: no (narrowing) in the PR body and changeset), run by this seat.


    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

Labels

area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobsdomain:serverDomain lane — seat card indexed by label:pm:seatpm:dispatchedpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions