Skip to content

Add v4 hook-registration + thrown-hook envelope repro#104

Closed
heskew wants to merge 2 commits into
v1.xfrom
bugfix/onresolveprovider-hook-repro
Closed

Add v4 hook-registration + thrown-hook envelope repro#104
heskew wants to merge 2 commits into
v1.xfrom
bugfix/onresolveprovider-hook-repro

Conversation

@heskew
Copy link
Copy Markdown
Member

@heskew heskew commented May 27, 2026

Summary

Adds `scripts/v4-hook-repro.mjs` to the v1.x line. Sibling of the existing `scripts/v4-routing-repro.mjs` (merged in #103). Where the routing-repro covers static-provider URL parsing, this one covers the `onResolveProvider` hook — registered from a sibling `resources.js`, the pattern CM uses.

Two test cases:

# Scenario Expected
1 Hook returns a config for an `oac-*` provider 302 to the hook's authorize URL with the hook's `client_id`
2 Hook throws HTTP 200 with envelope `{"status":500,"body":{"error":"Failed to resolve OAuth provider"}}` — exactly what Dawson reported on 2026-05-22

Both pass on `harperdb 4.7.19` + the in-tree plugin source. The script:

  • mkdtemp's a fresh tempRoot per run
  • npm pack's the local plugin into the fixture
  • writes a CM-style `config.yaml` + `resources.js` (top-level `registerHooks` call)
  • spawns `harperdb` with the same CLI-arg pattern as `v4-routing-repro`
  • saves / restores `~/.harperdb/hdb_boot_properties.file` so it leaves no trace on a clean exit

Two findings landed in memory during this work

  1. v4 vs v5 Resource return-shape translation differs: `return { status: 500, body: ... }` from a Resource method surfaces as HTTP 500 on harper v5 but as HTTP 200 with the envelope as the JSON body on harperdb v4. We had been reading Dawson's reported string as an HTTP 500 the whole time; it's actually a 200-with-envelope.

  2. Latent v5 regression in `registerHooks` from `resources.js` (observed during PR Add integration test: OAuth Resource path-segment routing #102 work, not yet formally repro'd): hooks register correctly on harperdb v4 but silently never fire on harper v5. When CM eventually migrates to v5, the documented multi-tenant SSO pattern breaks.

Companion PR

HarperFast/central-manager#372 adds the log-and-rethrow inside CM's `handleResolveProvider`, which combined with this repro should let Dawson actually see the underlying exception on his next failing request.

Test plan

  • `node scripts/v4-hook-repro.mjs` — overall: PASS
  • Boot props file is preserved across a clean run
  • (out of scope) v5 counterpart that demonstrates the hook-registration regression

🤖 Generated with Claude Code

heskew and others added 2 commits May 26, 2026 16:19
Mirrors CM's hook registration pattern in a sibling repro script to
the existing v4-routing-repro. The fixture:

  - config.yaml declares jsResource:resources.js (auto-load) + the
    OAuth plugin with one static provider literally named "oauth"
    (kept as a decoy for routing regressions).
  - resources.js calls `registerHooks({ onResolveProvider: ... })`
    at module top level. The hook returns a generic provider config
    for any oac-* providerName.

The script hits /oauth/oac-test-config/login and asserts the redirect
went to the URL the hook returned — empirical proof that on harperdb
v4 the hook DOES fire when registered from a sibling resources.js.

Why this matters. We previously suspected (from a v5 fixture attempt
on oauth main) that the same registerHooks-from-resources.js pattern
suffers from module isolation between resources.js's import of
@harperfast/oauth and the plugin's own pluginModule load. CM
demonstrably works in production, but on harper v5 the same pattern
broke. This script narrows that to a v4-vs-v5 component-loader
behavior split — and confirms that CM's setup is correct for v4.

For Dawson's actual 500: the hook IS registered on v4 (this script
proves it), so the 500 must come from inside CM's handleResolveProvider
itself — most likely a SecretManager.decrypt failure or DB error.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a second test case to v4-hook-repro: when the hook throws, the
plugin surfaces the harperdb-v4 error envelope

  HTTP/1.1 200 OK
  Content-Type: application/json

  {"status":500,"body":{"error":"Failed to resolve OAuth provider"}}

which is byte-for-byte what Dawson pasted in Slack on 2026-05-22. We
were reading that string as an HTTP 500 the whole time; it's actually
an HTTP 200 with the plugin's intended status nested in the body —
harperdb v4 doesn't translate a Resource's `return { status: 500, ... }`
to an HTTP 500 (harper v5 does).

This finalizes the repro:
  case 1: hook fires and returns config → 302 to the hook's URL
  case 2: hook throws → v4 envelope with 'Failed to resolve OAuth
          provider' as the inner body

For Dawson's investigation: the actual throw on his system is inside
CM's handleResolveProvider — SecretManager.decrypt, OrganizationOAuthConfig.get,
or SecretManager.create. To narrow further, CM needs try/catch + log
inside that function on his deployment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

Reviewed; no blockers found.

@claude
Copy link
Copy Markdown

claude Bot commented May 27, 2026

Reviewed; no blockers found.

@heskew heskew marked this pull request as ready for review May 28, 2026 18:32
@heskew
Copy link
Copy Markdown
Member Author

heskew commented May 28, 2026

Closing — superseded by HarperFast/central-manager#372 (merged).

#372 adds structured try/catch logging + rethrow inside CM's real handleResolveProvider, which captures the actual throw path on the actual failing record in dev/prod. That's strictly better than this script's synthetic throw new Error(...) for diagnosing Dawson's failure.

This repro already paid out its real value by being run, not merged — it proved two things that are now banked:

  • The onResolveProvider hook does fire on harperdb v4 from CM's resources.js + top-level registerHooks pattern (Registered OAuth hooks: onResolveProvider), which placed Dawson's bug inside the hook body rather than in registration.
  • Dawson's reported "500" is HTTP 200 with a {"status":500,"body":{"error":"Failed to resolve OAuth provider"}} envelope — a harperdb-v4 Resource return-shape quirk, not an HTTP 500.

Its only residual value would be a plugin-side regression guard ("does registerHooks from resources.js still fire on v1.x"), but it's a manual scripts/ artifact not wired into CI, on a maintenance branch — so it wouldn't actually catch a regression. The forward-looking guard worth having is a v5 hook-registration integration test (where the hook currently does not fire — the known latent regression), tracked separately.

The script remains on branch bugfix/onresolveprovider-hook-repro if anyone wants to re-run it.


🤖 Posted by Claude on Nathan's behalf

@heskew heskew closed this May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant