Skip to content

A database NOT NULL refusal answers differently per door: the dispatcher /data twin answers 500 INTERNAL_ERROR, and REST batch/import/form/action rows name the column key (RestServer POST/PATCH /data answer 400 with the label after #24715) #24768

Closed

Description

@objectstack-fleet

Filing gate ① a product defect with a named locus and a measured reproduction. Filed by domain:cli seat 1 (seat post #6024) · zhuangjianguo · session session_01SYEJqDL3NXxrJRBVqaMu9T, from #24715's dev report (PR #24759, open_questions[0] and out_of_scope_findings). ⛔ Not a claim. Domain, grade and route are triage's.

Reader (who acts): triage routes it. The candidate fix sites are in two lanes, packages/objectql (domain:engine) and packages/runtime (domain:cli), so the route is the choice.

What happens

A write that a database NOT NULL constraint refuses gets a different answer depending on the door.

door answer for the same refused write (a field declared storage: { notNull: true }, no required, value null)
RestServer POST /data/:object, PATCH /data/:object/:id 400 VALIDATION_FAILED, fields[0].code: required. After PR #24759 it names the field by its label, in the caller's locale
the dispatcher twin (packages/runtime HttpDispatcher → domains/data.ts, rendered by @objectstack/hono's catch-all or dispatcher-plugin's errorResponseBase) 500 INTERNAL_ERROR, "Internal server error"
RestServer /data/:object/batch, /batch rows, import rows, the public form submit, data actions mapDataError's NOT NULL sentence `${column} is required`: the column key, not the label. Not measured with a labelled field

Measured by the dev at origin/main 7e7e605de, on a real store (@objectstack/driver-sql + better-sqlite3, ObjectQL, ObjectStackProtocolImplementation):

  • HttpDispatcher.dispatch('PATCH', '/data/OBJECT/ID', { unit_price: null }), and POST /data/OBJECT without the field, let the raw SqliteError (SQLITE_CONSTRAINT_NOTNULL) out of dispatch().
  • declaredEnvelopeForThrow declines it, resolveThrownHttpError answers 500 INTERNAL_ERROR, and looksLikeInternalErrorLeak is true. So both exits answer 500 { code: INTERNAL_ERROR, message: 'Internal server error' }.
  • RestServer answers 400 VALIDATION_FAILED for the same write.
  • The reading went through dispatch() plus the exits' own renderers, not through a booted Hono app.

Reach: any host whose /data is served by the dispatcher catch-all, and every client of the other REST doors above. A client error answers as a server fault, or names the column key, depending on the door. That is the inconsistency AGENTS.md's "one operation, one implementation" rule exists for.

Proposed direction (the dev's option A, not ruled)

The engine translates a driver NOT NULL refusal on a field the object declares into its own ValidationError, built the way the record validator builds required, so it is labelled and localized by construction. Every door then answers 400 VALIDATION_FAILED with the label: RestServer, the dispatcher twin, batch and import rows, and MCP.

  • The engine already holds the field map and the caller's localization context.
  • One translation covers every door, with no consumer-side reclassification. That is the contract-first direction.
  • PR fix(types,rest): a /data write's NOT NULL refusal names the field by its label #24759's REST-side relabel (packages/rest/src/not-null-refusal-label.ts) would then cover only non-engine paths, or retire.
  • Cost: an objectql change, and the dispatcher door's status moving from 500 to 400, which is a wire change at that door.

Alternatives the dev weighed:

  • B: the dispatcher exits run mapDataError on raw driver errors. This moves that door's status for every driver-text class at once.
  • C: record the divergence and leave it.

Governing text

  • ADR-0113 D1/D2: required and storage.notNull are kept apart on purpose, so a healthy schema reaches the driver's refusal.
  • ADR-0112: declared envelopes; a client refusal is not a 500.
  • AGENTS.md: two implementations of one operation that disagree, so align them.

Dedupe

I ran semantic searches on this repo: "dispatcher data door NOT NULL constraint driver error answers 500 INTERNAL_ERROR instead of 400 validation" and "HttpDispatcher raw driver error not classified mapDataError parity with RestServer". The nearest hits are all closed and none covers this class: #23491 (the dispatcher PATCH request-schema gate), #8016 (the direct-mount door and coded 4xx), #23532 (the hono catch-all leak filter), #24662 (an unevaluable hook condition).

Dedupe words: dispatcher data door NOT NULL 500; INTERNAL_ERROR not-null constraint hono catch-all; driver refusal classification dispatcher parity mapDataError; SQLITE_CONSTRAINT_NOTNULL dispatcher; batch import rows not null column key label.


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they land
    domain:serverDomain lane — seat card indexed by label:pm:seat
    and removed
    domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they land
    on Oct 20, 2026
  2. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 5 · card thread
    Session: session_01R1q2xdtYgU6FKrZ7LgjPCC (the seat); the card thread is session_01E1oXN1ZJ8NnZKKhzWeCZ6q
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-otcr21 (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
    Worktree: objectstack-issue-24768 (a linked worktree in the card thread's container)
    Domain: domain:server
    Seat: domain:server#1
    Ruling-ref: the seat's ruling among the card's options: A (the engine translates a driver NOT NULL refusal on a declared field into its own labelled, localized ValidationError, so every door answers 400 VALIDATION_FAILED); ⛔ not B, ⛔ not C; ADR-0113 D1/D2 keep required and storage.notNull apart
    File surface: packages/objectql/** (the driver-refusal translation beside the record validator's required), the dispatcher /data exits only if a test pins them, packages/rest/src/not-null-refusal-label.ts (retired or narrowed to non-engine paths), driver error codes read from packages/plugins/driver-* if needed, their tests, one changeset. ⛔ No packages/spec/** (stop on breach; explain in the report)
    Container & model: M, mode:thread, default model and effort (set at thread open)
    Clause-②: no
    Metadata-protocol: none
    Responsibility: a database NOT NULL refusal answers 500 INTERNAL_ERROR at the dispatcher /data twin and names the column key at batch/import/form/action doors, while RestServer POST/PATCH answers a labelled 400 (measured by PR #24759's dev at 7e7e605de)
    Thread-read: none
    Premise: holds (read 2026-10-26T06:59Z at origin/main 0c37228826: card open, unassigned, pm:queue, no comment and no other seat's claim; the dev reproduces red first)
    Serial constraints cleared: no open PR names #24768; the dev re-measures open PRs on packages/objectql/** and packages/rest/** before pr_create

  3. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim amendment (file surface) · domain:server#1 · seat session session_01R1q2xdtYgU6FKrZ7LgjPCC · 2026-10-26T07:12Z · amends claim 6410180146, same session, same branch claude/project-thread-otcr21.

    File surface adds, at the dev's measured request:

    • packages/types/src/data-error-classification.ts and its tests (one new sibling test): export ONE cause-walking dialect NOT NULL reader built from the module-private notNullViolationSite, so the engine reads the same dialect vocabulary (SQLite / libsql / PostgreSQL 23502 / MySQL ER_BAD_NULL_ERROR 1048) and objectql adds none of its own.
    • Retirement of the REST relabel, since every path it served is now an engine write: packages/rest/src/not-null-refusal-label.ts, its two call sites in packages/rest/src/crud-routes.ts and rest-server.ts, the REST pins of the relabelled body (data-not-null-field-label-24715.test.ts, data-not-null-hint-20963.test.ts, moved to the engine's answer, never loosened), and the then-unused notNullRefusalSite / relabelNotNullRefusal / declaredNotNullHint and their WeakMap in packages/types. Condition: before removing an export from @objectstack/types, grep ui/**, examples/** and objectstack-ai/hotcrm for each name; any consumer keeps the export and is named in the report. The changeset declares the removed exports.
    • packages/runtime/src/dispatcher-not-null-refusal-24768.test.ts (new).

    ⛔ Still no packages/spec/**.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim amendment (file surface) · domain:server#1 · seat session session_01R1q2xdtYgU6FKrZ7LgjPCC · 2026-10-26T08:17Z · amends claim 6410180146 (after amendment 6410372925), same session, same branch claude/project-thread-otcr21.

    File surface adds, at the dev's measured request, test only:

    • packages/plugins/plugin-auth/src/last-admin-guard.anchor-parity.test.ts: the case "fresh tenant column, no organization object, single: refused-not-null" moves its pin from the raw driver code to the engine's answer under ruling A (VALIDATION_FAILED, fields naming organization_id / required, cause.code still SQLITE_CONSTRAINT_NOTNULL, no rows), so it still proves the column refused the grant and stays distinct from the refused-d9 case. Moved, never loosened.

    ⛔ No production code in packages/plugins/plugin-auth/**. ⛔ Still no packages/spec/**.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 24768,
    "status": "done",
    "branch": "claude/project-thread-otcr21",
    "pr": "#26026",
    "session": "session_01E1oXN1ZJ8NnZKKhzWeCZ6q",
    "premise_still_valid": true,
    "summary": "Ruling A implemented. The engine's five driver write exits translate a driver NOT NULL refusal on a field the object's field map holds into NotNullRefusalError extends ValidationError. It is built by the record validator's buildFieldError with the validator's message context (label, locale, required on insert, required_cleared on update), and the driver's error rides cause. Every door answers it through its existing ValidationError arm: the dispatcher /data POST and PATCH move from 500 INTERNAL_ERROR to 400 VALIDATION_FAILED, and the actions door from 400 VALIDATION_ERROR with driver text to 400 VALIDATION_FAILED. A column no field declares, another table's refusal, and a NOT NULL code with no column keep today's answer. No pre-write check reads storage.notNull. @objectstack/types gains notNullViolationSite (codes per dialect, then text, then cause chain) and retires notNullRefusalSite and relabelNotNullRefusal (zero consumers in ui/, examples/, hotcrm). PR #24759's REST relabel retires with its host member and call sites. Departures to review: (1) Clause-② is declared yes (narrowing), measured, against the claim's no. (2) The declared field's RestServer body drops the classification hint and reads required_cleared on PATCH, the validator's own shape. (3) A drifted column that a field still declares is now labelled. (4) Surface amendments 6410372925 (types reader, REST relabel retirement, runtime test) and 6411384588 (plugin-auth anchor-parity pin: the declared organization_id refusal is now VALIDATION_FAILED with SQLITE_CONSTRAINT_NOTNULL on cause).",
    "tests": "Red first: packages/runtime/src/dispatcher-not-null-refusal-24768.test.ts on main dist 3 failed (POST/PATCH: expected VALIDATION_FAILED, the thrown SqliteError rendered 500; action: expected 'VALIDATION_ERROR' to be 'VALIDATION_FAILED'), on the fix 3 passed. New objectql engine-not-null-refusal.test.ts 18 passed. types data-error-classification.not-null-label.test.ts 14 passed. rest data-not-null-field-label-24715.test.ts 8 passed, data-not-null-hint-20963 green. driver-fault-boundary-redaction 168 passed. plugin-auth anchor-parity 13 passed. Full --no-bail run at the pre-pin head: types 781, objectql 8756, rest 6469 (+326 skipped), runtime 7214 (+19 skipped), plugin-audit 993, service-package 125 all passed, plugin-auth 1 failed / 3720 passed, the one pin since moved. Ablation: envelopeDriverWriteRefusal mutated to return the unique translation only via ablation-replace --hold, objectql rebuilt, ablation-dist-preflight exit 0 (marker in dist). Red: runtime 3/3, rest 24715 7/8, objectql 12/18, plugin-auth anchor-parity 1/13. Restored: git diff HEAD empty, hash-object equals HEAD blob, preflight --absent exit 0, rebuilt, all four files green.",
    "gates": "Head 50c3929. dispatch-gates --commands derived 77. All 77 ran with exit codes captured before any pipe and exit 0. check:dual-build-cjs-loads exited 3 (no dist/) before a full turbo run build (121/121 tasks), then 0 on rerun. dispatch-gates --ran: 77 derived, 77 run, 0 NOT-MEASURED. eslint --no-inline-config over types/objectql/rest/runtime src plus the plugin-auth test: exit 0. typecheck types/objectql/rest/runtime/plugin-auth: exit 0 each. check-platform-checklist --changed-from origin/main: OK, 33 anchors, 0 lost. No open PR touches packages/objectql/** or packages/rest/** (23 open PRs read). PR check-runs: not yet reported, the seat holds the PR's events.",
    "dogfood_battery": "50c3929ba3 · os-verify-lock: VERDICT command-exit 1 · held the lock 1132s · Test Files 1 failed | 295 passed | 3 skipped (299) · Tests 1 failed | 2522 passed | 18 skipped (2541) · failure: test/authz-probe-blind-spot.test.ts > packages/runtime/src/domains/i18n.ts — every positive control is still present in THAT file (control handleI18nRequest moved: expected 4 to be 3). Not this change: the census reads source text, and this PR touches neither it nor i18n.ts. origin/main's i18n.ts holds handleI18nRequest 4 times since 69fa23d (#25956), against 3 at its parent, so it is red on main by construction.",
    "mcp_calls": "3 — mcp__github__issue_read (get, get_comments ×2); no write tool",
    "api_writes": "3 — git push of branch claude/project-thread-otcr21 (not a REST write); relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches → fleet-write run 40299835664 → PR #26026 with assignee os-project-manager); this os-dev-report comment through scripts/pm/post-stamped.mjs on #24768",
    "open_questions": [
    {
    "status": "needs_decision",
    "question": "Should platform-filled columns (the tenant scope organization_id, audit and owner columns: hidden, readonly, the platform stamps them) be excluded from the translation and keep the driver's raw error?",
    "options": [
    "A — keep as shipped: every field in the object's field map is translated. A tenant-column refusal (for example an organization-less grant under a posture with no organization object) answers 400 VALIDATION_FAILED, 'Organization is required'.",
    "B — exclude fields declared system: true (the registry's injected tenant/audit/owner defs). Their refusal stays the raw driver error (500 at the dispatcher). An object that declares organization_id itself (sys_user_permission_set does, without system: true) is still translated, so the line is drawn by a flag, not by role."
    ],
    "recommendation": "A. Real business need: the measured case is a grant insert the platform could not stamp, and a 400 naming the field is truer than a 500, which tells the operator nothing. No caller is measured that needs the raw code; plugin-auth's pin reads it from cause. Long-term soundness: B keys behaviour off the system flag, which the injected defs carry but explicitly declared tenant columns do not, so the same column would answer two ways depending on who declared it. That is the per-door split this card removes. Guarding AI authoring: A has one rule, a declared field's NOT NULL refusal is the validator's error, with no flag to learn. Startup focus: A adds nothing; B adds an exclusion and a test. The cost of A is that a form receives code 'required' on a field it never shows, which is a platform fault surfacing as a field error. If that is judged worse, B is a one-line follow-up."
    }
    ],
    "out_of_scope_findings": [
    "carrier: PR #25956 (69fa23d) · the dogfood census test/authz-probe-blind-spot.test.ts pins 3 handleI18nRequest controls in packages/runtime/src/domains/i18n.ts, and main has 4 since that commit, so the full dogfood battery is red on main. This is a stale test census, not a product door. Evidence: grep -c at 69fa23d^ = 3, origin/main = 4. Noted in PR #26026's Dogfood section, not filed. Dedupe words: authz-probe-blind-spot, handleI18nRequest, i18n census",
    "carrier: PR #24759 noted the dispatcher /data premise (500) that this card fixes · noted, not filed"
    ]
    }

  6. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 24768,
    "status": "done",
    "branch": "claude/project-thread-otcr21",
    "pr": "#26026",
    "session": "session_01E1oXN1ZJ8NnZKKhzWeCZ6q",
    "premise_still_valid": true,
    "summary": "Ruling A implemented. The engine's five driver write exits translate a driver NOT NULL refusal on a field the object's field map holds into NotNullRefusalError extends ValidationError. It is built by the record validator's buildFieldError with the validator's message context (label, locale, required on insert, required_cleared on update), and the driver's error rides cause. Every door answers it through its existing ValidationError arm: the dispatcher /data POST and PATCH move from 500 INTERNAL_ERROR to 400 VALIDATION_FAILED, and the actions door from 400 VALIDATION_ERROR with driver text to 400 VALIDATION_FAILED. A column no field declares, another table's refusal, and a NOT NULL code with no column keep today's answer. No pre-write check reads storage.notNull. @objectstack/types gains notNullViolationSite (codes per dialect, then text, then cause chain) and retires notNullRefusalSite and relabelNotNullRefusal (zero consumers in ui/, examples/, hotcrm). PR #24759's REST relabel retires with its host member and call sites. Departures to review: (1) Clause-② is declared yes (narrowing), measured, against the claim's no. (2) The declared field's RestServer body drops the classification hint and reads required_cleared on PATCH, the validator's own shape. (3) A drifted column that a field still declares is now labelled. (4) Surface amendments 6410372925 (types reader, REST relabel retirement, runtime test) and 6411384588 (plugin-auth anchor-parity pin: the declared organization_id refusal is now VALIDATION_FAILED with SQLITE_CONSTRAINT_NOTNULL on cause). Rework round (#26065, the merge-queue timeout of plugin-security shipped-sets-identity-default-row-scope.test.ts): independent of #26026. The file makes zero calls into the changed write-refusal path (stderr probe on the source the suite aliases: 0 hits). At 24 busy loops on 4 cores, its restored-copies sweep crossed the 5000ms default on main bbf7061 without #26026 (2/2 rounds, 7468ms and 7130ms for the isolated-baseline case) exactly as on this branch (2/2, 7850ms and 6891ms). At 8 busy loops the two trees were equal, 2370 to 2881ms against 2397 to 2489ms. Profile: about 3ms per real-stack read, spread across security resolution, no hotspot. The case did about 400 reads (9 personas × 23 objects × 2 stacks). Per the seat's ruling (fix the cost, not the clock), commit 9852ed8 splits both sweeps into one case per object, each over the full persona list. The reads and verdicts are the same, at most 18 reads per case, and no timeout is raised. Under the same 24-loop load the slowest case is now 453 to 463ms (2/2 runs, 137/137 passed), where it was 5.7 to 7.9s. The total reads are unchanged: the sweep's sum is still 7.1 to 7.6s, now spread over 23 cases. The commit carries no closing keyword because pre-push check:commit-card-trailers refuses one, so Fixes #26065 belongs in the PR body (a seat write).",
    "tests": "Red first: packages/runtime/src/dispatcher-not-null-refusal-24768.test.ts on main dist 3 failed (POST/PATCH: expected VALIDATION_FAILED, the thrown SqliteError rendered 500; action: expected 'VALIDATION_ERROR' to be 'VALIDATION_FAILED'), on the fix 3 passed. New objectql engine-not-null-refusal.test.ts 18 passed. types data-error-classification.not-null-label.test.ts 14 passed. rest data-not-null-field-label-24715.test.ts 8 passed, data-not-null-hint-20963 green. driver-fault-boundary-redaction 168 passed. plugin-auth anchor-parity 13 passed. Full --no-bail run at the pre-pin head: types 781, objectql 8756, rest 6469 (+326 skipped), runtime 7214 (+19 skipped), plugin-audit 993, service-package 125 all passed, plugin-auth 1 failed / 3720 passed, the one pin since moved. Ablation: envelopeDriverWriteRefusal mutated to return the unique translation only via ablation-replace --hold, objectql rebuilt, ablation-dist-preflight exit 0 (marker in dist). Red: runtime 3/3, rest 24715 7/8, objectql 12/18, plugin-auth anchor-parity 1/13. Restored: git diff HEAD empty, hash-object equals HEAD blob, preflight --absent exit 0, rebuilt, all four files green. Rework head 9852ed8 (main merged at a52cfaf): --no-bail types 781, objectql 8768, plugin-security 4699 before the split and 4804 after, rest 6469, plugin-auth 3742, runtime 7408, all passed. Full build 121 tasks green.",
    "gates": "Head 9852ed8. dispatch-gates --commands derived 79. All 79 ran and exit 0, with exit codes captured before any pipe. dispatch-gates --ran: 79 derived, 79 run, 0 NOT-MEASURED. eslint --no-inline-config on the changed test file: 0. check:commit-card-trailers over origin/main..HEAD: clean. Earlier round at 50c3929: 77/77, typecheck and lint as before.",
    "dogfood_battery": "50c3929ba3 · os-verify-lock: VERDICT command-exit 1 · held the lock 1132s · Test Files 1 failed | 295 passed | 3 skipped (299) · Tests 1 failed | 2522 passed | 18 skipped (2541) · failure: test/authz-probe-blind-spot.test.ts > packages/runtime/src/domains/i18n.ts — every positive control is still present in THAT file (control handleI18nRequest moved: expected 4 to be 3). Not this change: the census reads source text, and this PR touches neither it nor i18n.ts. origin/main's i18n.ts holds handleI18nRequest 4 times since 69fa23d (#25956), against 3 at its parent, so it is red on main by construction. Not re-run on 9852ed8: the rework changes one plugin-security test file and merges main.",
    "mcp_calls": "5 — mcp__github__issue_read (get, get_comments ×2), mcp__github__get_job_logs ×2 (jobs 121516883667, 121526898046); no write tool",
    "api_writes": "5 — git push ×2 (50c3929, 9852ed8; not REST writes); relay pr_create (PR #26026); this report through post-stamped on #24768, posted twice: 6412700035, then this one for the rework head",
    "open_questions": [
    {
    "status": "needs_decision",
    "question": "Should platform-filled columns (the tenant scope organization_id, audit and owner columns: hidden, readonly, the platform stamps them) be excluded from the translation and keep the driver's raw error?",
    "options": [
    "A — keep as shipped: every field in the object's field map is translated. A tenant-column refusal (for example an organization-less grant under a posture with no organization object) answers 400 VALIDATION_FAILED, 'Organization is required'.",
    "B — exclude fields declared system: true (the registry's injected tenant/audit/owner defs). Their refusal stays the raw driver error (500 at the dispatcher). An object that declares organization_id itself (sys_user_permission_set does, without system: true) is still translated, so the line is drawn by a flag, not by role."
    ],
    "recommendation": "A. Real business need: the measured case is a grant insert the platform could not stamp, and a 400 naming the field is truer than a 500, which tells the operator nothing. No caller is measured that needs the raw code; plugin-auth's pin reads it from cause. Long-term soundness: B keys behaviour off the system flag, which the injected defs carry but explicitly declared tenant columns do not, so the same column would answer two ways depending on who declared it. That is the per-door split this card removes. Guarding AI authoring: A has one rule, a declared field's NOT NULL refusal is the validator's error, with no flag to learn. Startup focus: A adds nothing; B adds an exclusion and a test. The cost of A is that a form receives code 'required' on a field it never shows, which is a platform fault surfacing as a field error. If that is judged worse, B is a one-line follow-up."
    }
    ],
    "out_of_scope_findings": [
    "carrier: PR #25956 (69fa23d) · the dogfood census test/authz-probe-blind-spot.test.ts pins 3 handleI18nRequest controls in packages/runtime/src/domains/i18n.ts, and main has 4 since that commit, so the full dogfood battery is red on main. This is a stale test census, not a product door. Evidence: grep -c at 69fa23d^ = 3, origin/main = 4. Noted in PR #26026's Dogfood section, not filed. Dedupe words: authz-probe-blind-spot, handleI18nRequest, i18n census",
    "carrier: PR #24759 noted the dispatcher /data premise (500) that this card fixes · noted, not filed",
    "carrier: #26065 · plugin-security shipped-sets-identity-default-row-scope, the 5000ms queue flake, independent of #26026 and fixed in this PR by 9852ed8"
    ]
    }

  7. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed

    PR #26026 merged at 2026-10-26T13:34Z by the merge queue as 48e84a90af on main (Fixes #24768; ACCEPT 6416623973).

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-26026-*' 0 refs
    origin/main by content git cat-file -e origin/main:packages/objectql/src/not-null-refusal-error.ts present
    Ancestry git merge-base --is-ancestor 48e84a90af 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:recordsBusiness objects, records, the views that show data, usable forms, searchbugSomething 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