From 60b144fbbf7549a883584680548d117a61db66ad Mon Sep 17 00:00:00 2001 From: kjgbot Date: Sat, 12 Sep 2026 20:54:01 +0200 Subject: [PATCH] test(sdk): expand actionable-message pattern to other lint pins (#228 followup) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to #228 (merged as #371). Three additional cryptic throw sites extended with the (a) file:line to edit, (b) fix hint, (c) reason-for-pin pattern: - packages/sdk/tests/webhook.test.ts:29 — non-TCP server.address() explains the three likely causes (unawaited startup / socket-path port / exhausted ephemerals) rather than 'missing HTTP address'. - scripts/schema-metaschemas.mjs:45 — Unbundled meta-schema reference now names the roots list to add the schema to and explains the pin (unresolvable $ref would make Ajv throw at every consumer). - packages/sdk/tests/authored-use-loader.test.ts:22 — the body throw fixture now names the invariant it guards (loader must walk header only) and points at execute-authored-flow's gating signal. Not-in-scope: other test throws that fire when the SUT expected error (mock rejections, integration-test timing) are already meaningful in context. Co-Authored-By: Claude Opus 4.7 (1M context) Session-Id: efeda5df-9b7c-48d4-b2ce-957f5bef0a82 Session-Id: efeda5df-9b7c-48d4-b2ce-957f5bef0a82 --- packages/sdk/tests/authored-use-loader.test.ts | 9 ++++++++- packages/sdk/tests/webhook.test.ts | 13 ++++++++++++- scripts/schema-metaschemas.mjs | 12 +++++++++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/packages/sdk/tests/authored-use-loader.test.ts b/packages/sdk/tests/authored-use-loader.test.ts index 4f083417b..e9009774a 100644 --- a/packages/sdk/tests/authored-use-loader.test.ts +++ b/packages/sdk/tests/authored-use-loader.test.ts @@ -19,7 +19,14 @@ function fixture(files: Record): string { writeFileSync(join(directory, `${name}.flow.ts`), ` import { flow } from '@relayflows/surface'; export default flow(${JSON.stringify(name)}, { use: ${JSON.stringify(use)} }, async f => { - throw new Error('loader must never execute authored bodies'); + // The authored body must NEVER run during use: resolution — the loader + // only walks the header. If you see this thrown by a test in + // packages/sdk/tests/authored-use-loader.test.ts, some loader code path + // is invoking the body when it should be inspecting the header only. + // Track the invocation site and gate it on the same signal that + // execute-authored-flow uses (see 'preflightHelpers' or the compile + // pass, not the body). + throw new Error('loader-invoked-body: use: resolution must not execute authored bodies (see authored-use-loader.test.ts)'); }); `); } diff --git a/packages/sdk/tests/webhook.test.ts b/packages/sdk/tests/webhook.test.ts index be0073189..57ccded87 100644 --- a/packages/sdk/tests/webhook.test.ts +++ b/packages/sdk/tests/webhook.test.ts @@ -26,7 +26,18 @@ async function receiver(dir: string): Promise { const server = await startWebhookServer(dir, 0); servers.push(server); const address = server.address(); - if (!address || typeof address === 'string') throw new Error('missing HTTP address'); + if (!address || typeof address === 'string') { + // startWebhookServer returned before the TCP socket bound (address()===null) + // or bound to a UNIX socket path (typeof 'string'). Neither shape is usable + // for the http:// URL these tests hand to the receiver. If you hit this: + // - Verify startWebhookServer is awaited before receiver() returns. + // - Confirm the second arg (port) is a number, not a socket path. + // - Check that a prior test didn't hold onto port 0 or exhaust ephemeral ports. + throw new Error( + 'webhook receiver: server.address() returned a non-TCP address; ' + + `see packages/sdk/tests/webhook.test.ts:${28}`, + ); + } return `http://127.0.0.1:${address.port}`; } diff --git a/scripts/schema-metaschemas.mjs b/scripts/schema-metaschemas.mjs index 504c44cd1..5952a968e 100644 --- a/scripts/schema-metaschemas.mjs +++ b/scripts/schema-metaschemas.mjs @@ -42,7 +42,17 @@ export function outputMetaschemas(require) { const fragment = target.hash; target.hash = ''; const name = ids.get(target.href); - if (!name) throw new Error(`Unbundled meta-schema reference ${target.href}`); + if (!name) { + throw new Error( + `Unbundled meta-schema reference ${target.href}.\n` + + `Add the referenced schema's $id to the bundled roots list in\n` + + `scripts/schema-metaschemas.mjs so this generator can inline it under\n` + + `#/$defs/. Bundled roots are the entries fed to \`ids\`. This pin\n` + + `exists so a new schema can't silently produce a JSON Schema file with\n` + + `an unresolvable external $ref — Ajv would then throw at load time and\n` + + `every consumer would see a runtime failure with no context.`, + ); + } result.$ref = `#/$defs/${name}${fragment.startsWith('#/') ? fragment.slice(1) : ''}`; } else if (key === 'dependencies') { result.dependentRequired = child;