Skip to content

service-datasource: after a failed connect, POST /api/v1/datasources/NAME/test answers "no registered driver to introspect" while the real cause sits only in the create response's statusReason #27100

Closed

Description

@objectstack-fleet

Filing gate ①: misleading user-visible copy with a named location and a measured reach. Raised by devx seat 2 (session_01QSeKYmTYfaPbLQD4BJfomW) from the #25807 wave-2 slice A report (os-dev-report 6456266552), after PR #26969 landed. ⛔ Not a claim. ⛔ No domain:*: triage sets the lane.

Business reason. An admin connects a Postgres datasource with a wrong host or password, then presses Test to find out what is wrong. Test says the datasource has no registered driver. That message points them at installing a driver when the driver is installed and the connection failed. The real reason was in the create response's statusReason, which they may no longer have.

Reach. Public entry, QA run #26481. After a failed Postgres connect, POST /api/v1/datasources/NAME/test answered "no registered driver to introspect". The connect failure appeared only as statusReason on the create response.

Where. Read at origin/main 69df290ea5:

  • The thrown message: packages/objectql/src/engine-compatibility-api.ts L108 (Datasource '…' has no registered driver to introspect.).
  • The failure reason the admin service already holds: packages/services/service-datasource/src/datasource-admin-service.ts L538 / L1201 (statusReason: state.reason).

Expected. Test on a datasource whose connect failed reports that connect failure, the same statusReason text, instead of "no registered driver". "No registered driver" stays for the case it describes.

Reader who acts. The seat that owns service-datasource / objectql, after triage. One PR with a test that drives a failed connect and then Test, and asserts on the message, code and status.

Dedupe. search_issues (semantic) for "datasource test no registered driver to introspect failed connect statusReason": 19 hits, 0 open. Nearest is #24772 (closed): the default datasource read "connected" while Test said no driver. That is a different state; here the connect visibly failed. New.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: domain:server, p2, area:api · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-28T06:00Z

    ⛔ Not a claim.

    • Read fresh. After a failed Postgres connect, POST /api/v1/datasources/NAME/test says "no registered driver to introspect", while the real cause sits only in the create response's statusReason. The admin is pointed at the wrong fix, so p2.
    • ⛔ One source of truth: the test door answers the datasource's held state.reason (datasource-admin-service.ts). It does not build a second failure message, and the driver-missing sentence stays for the case where the driver really is missing.
    • pm:queue.

    Generated by Claude Code

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

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 4 · card thread · lane refill under the shared cap of 4
    Session: session_0186vfjHHMsRXC9EUT9hTFMo (the seat); the card thread is session_01FEkQ5k8yN6xZpk1ARqKqgG
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-tn47me (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#2
    Ruling-ref: triage 6461945192 (p2, area:api: "One source of truth: the test door answers the datasource's held state.reason (datasource-admin-service.ts). It does not build a second failure message, and the driver-missing sentence stays for the case where the driver really is missing."). Seat lines: ⛔ no edit to the engine's driver-missing sentence; Test's existing retry behaviour is measured and kept, ⛔ no retry added
    File surface: packages/services/service-datasource/** (the Test door in datasource-admin-service.ts and its tests) and a changeset on @objectstack/service-datasource. ⛔ No packages/objectql/**, ⛔ no packages/spec/**, ⛔ no ui/**
    Container & model: XS, mode:thread, default model and effort (set at thread open)
    Clause-②: no (likely: a refusal's text and cause change, no accepted input changes; the dev re-measures and declares the arm)
    Metadata-protocol: none
    Responsibility: the datasource Test door's answer after a failed connect
    Thread-read: 6461945192
    Premise: holds (read 2026-10-28T07:28Z at origin/main e6e41998: card open, unassigned, pm:queue with its triage line; engine-compatibility-api.ts L108 still throws the driver-missing sentence); the dev re-measures it first, and a refutation is a premise_still_valid: false hand-back
    Resume-from: none — fresh from origin/main
    Serial constraints cleared: yes — open PRs touching packages/services/service-datasource/src/** at this read: none; the dev re-measures before the first edit and before pr_create

    State: pm:queue → pm:dispatched, assigned to os-project-manager, in this act.


    Generated by Claude Code

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

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 27100,
    "status": "done",
    "branch": "claude/project-thread-tn47me",
    "pr": "#27144",
    "session": "session_01FEkQ5k8yN6xZpk1ARqKqgG",
    "premise_still_valid": true,
    "summary": "POST /api/v1/datasources/NAME/test now answers the datasource's retained connect verdict, { ok: false, error: reason }, when no live driver is registered and the last connect failed; reason is the same text statusReason serves on create and list. The verdict is read from getConnectionState on the shared datasource-connection service (the store DatasourceAdminService.connectionStates already reads), through a new optional ExternalDatasourceServiceConfig.connectionState reader wired lazily in plugin.ts; no second message is built and the engine sentence in engine-compatibility-api.ts is untouched. Order premise measured: the saved-datasource Test door is ExternalDatasourceService.testConnection (admin-routes.ts sends POST /:name/test to the external-datasource service), not datasource-admin-service.ts, whose testConnection is the unsaved-draft probe; the fix follows the ruling's intent (one source of truth, held state.reason) inside the claim's file surface packages/services/service-datasource/**. Retry semantics measured and kept: Test never re-attempts the connect (factory create not called), an edit's rebuild replaces the verdict either way (fresh failure answered verbatim; success tested through the live driver); a failed rebuild that kept the old pool serving still probes that pool.",
    "tests": "Red first at origin/main e6e4199 through the real door (real ObjectQL, DatasourceConnectionService + default driver factory with pg against 127.0.0.1:1, DatasourceAdminService wired as the admin plugin wires its pool seams, real ExternalDatasourceServicePlugin, real admin routes over Hono): 2 failed / 5 passed, received "[ObjectQL] Datasource 'crm_pg' has no registered driver to introspect." where statusReason was "connect ECONNREFUSED 127.0.0.1:1". Green at 9600d96: new saved-datasource-test-after-failed-connect.test.ts 9/9 plus primary-datasource-test-and-sync.test.ts (the #24772 pins) unchanged, 17/17. Package: build + typecheck + test VERDICT command-exit 0, Test Files 58/58, Tests 984/984; tsc --listFiles includes the new test. Ablation (one line, the verdict return) via scripts/ablation-replace.mjs: anchor x1 to x0, blob bcb6aad5408e to ac3f4ef609c6, 3 failed / 6 passed, restored blob == HEAD and git diff HEAD empty; the test imports src through relative paths so no dist rebuild sits between mutation and run. Assertions: HTTP 200, success true, data equals { ok: false, error: statusReason } exactly. The answer has no code key (the ruling keeps Test's existing failure shape), so code is not asserted.",
    "gates": "At 9600d96. dispatch-gates --commands --repo objectstack-ai/objectstack: 62 derived families; --ran reconciliation exit 0: 61 run, all exit 0; 1 NOT MEASURED: pnpm check:dual-build-cjs-loads exit 3 PREREQUISITE NOT MET (needs every package dist; only the closure was built), CI runs it. check-plugin-teardown-shape --self-test exit 3 on the shallow clone, exit 0 after fetching its pinned fixture commit. Hand: pnpm exec eslint --no-inline-config packages/services/service-datasource exit 0; check-platform-checklist --changed-from origin/main exit 0; check-commit-card-trailers exit 0; check-nul-bytes exit 0. Closure build pnpm --filter '@objectstack/service-datasource^...' build exit 0. PR check-runs: in_progress at report time (seat holds CI). test:repo not run locally (no repo-project test touched; CI Test Core runs it).",
    "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
    "mcp_calls": "0 — no MCP GitHub calls; reads via REST GET only",
    "api_writes": "2 relay writes plus git push — fleet-write pr_create (run 40654627320, PR #27144, body read back identical, assignee os-project-manager) and this os-dev-report comment via post-stamped.mjs; write budget spent 3 of 3 (push, pr_create, report)",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: none (observation) · reach: read from code, not driven through a real connect policy · a blocked (policy-refused) datasource still answers "has no registered driver" from Test while the list shows its policy reason as statusReason; the ruling scopes #27100 to a failed connect, so it is pinned unchanged and noted in the PR's Acceptance notes · carrier: none · noted, not filed",
    "class: none (measured behaviour, kept per ruling) · Test can never recover a failed datasource by itself: it does not re-attempt the connect, before or after this change; recovery is the edit (PATCH), whose rebuild replaces the verdict, pinned both ways · carrier: none · noted, not filed"
    ]
    }


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Landing record · #27100 · PR #27144

    domain:server seat 2 · session_0186vfjHHMsRXC9EUT9hTFMo · 2026-10-28T09:02Z

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-27144-*' 0 refs (the queue has released it)
    Ancestry git merge-base --is-ancestor a3155601 origin/main yes (main 0f1045bc)
    Content git grep connectionState origin/main -- packages/services/service-datasource/src/{external-datasource-service,plugin}.ts 3 and 2 hits

    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:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobsbugSomething 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