Skip to content

Commit 11e53c4

Browse files
czlonkowskiclaude
andcommitted
fix: compare release pins against installed versions, not declared ones (review round 5)
The skew warning and release resolution read the installed n8n-nodes-base version from node_modules instead of the package.json pin, so a stale install cannot pair this run's entity types with a schema neither belongs to; an unreadable install is itself reported. Conceived by Romuald Członkowski - www.aiadvisors.pl/en Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JXDW1LGvRXaQydK21X89sj
1 parent 0524fc7 commit 11e53c4

1 file changed

Lines changed: 19 additions & 3 deletions

File tree

scripts/check-settings-drift.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,15 @@ async function resolveSchemaRelease(
261261
return nodesBaseMatch ?? { version: nodesBase, pins: await fetchReleasePins(nodesBase) };
262262
}
263263

264+
/** The version actually installed, which a stale node_modules can hold apart from the pin. */
265+
function installedNodesBaseVersion(): string | null {
266+
try {
267+
return (require('n8n-nodes-base/package.json') as { version?: string }).version ?? null;
268+
} catch {
269+
return null;
270+
}
271+
}
272+
264273
function installedEntityPackageVersion(): string | null {
265274
try {
266275
const pkgPath = join(dirname(require.resolve('n8n-workflow')), '..', '..', 'package.json');
@@ -372,9 +381,15 @@ async function main(): Promise<void> {
372381
let entityProperties: Set<string> | null = null;
373382
let releasePins: ReleasePins | null = null;
374383
const installedEntity = explicitVersion ? null : installedEntityPackageVersion();
384+
const installedNodesBase = explicitVersion ? null : installedNodesBaseVersion();
375385
if (!explicitVersion) {
376386
entityProperties = parseEntitySettingsProperties(readEntityDeclarations());
377-
({ version, pins: releasePins } = await resolveSchemaRelease(version, installedEntity));
387+
// Match on what is installed, not what is declared - a stale node_modules would otherwise
388+
// pair this run's entity types with a schema neither of them belongs to.
389+
({ version, pins: releasePins } = await resolveSchemaRelease(
390+
installedNodesBase ?? version,
391+
installedEntity
392+
));
378393
}
379394

380395
console.log(`🔍 Checking workflow settings against n8n ${version}\n`);
@@ -386,9 +401,10 @@ async function main(): Promise<void> {
386401
// n8n-workflow while shipping a different n8n-nodes-base (and so a different schema).
387402
// The axis still runs: it can only fail loudly (a human investigates at update time),
388403
// never silently pass what a matching set would fail.
389-
const installedNodesBase = resolveVersion();
390404
const skews: string[] = [];
391-
if (releasePins && releasePins.nodesBase !== installedNodesBase) {
405+
if (!installedNodesBase) {
406+
skews.push('installed n8n-nodes-base version could not be read');
407+
} else if (releasePins && releasePins.nodesBase !== installedNodesBase) {
392408
skews.push(`n8n-nodes-base ${installedNodesBase} vs pin ${releasePins.nodesBase}`);
393409
}
394410
if (releasePins && installedEntity && releasePins.workflow !== installedEntity) {

0 commit comments

Comments
 (0)