fix(core): Fix task runner validation error on array of arrays (#15106)

This commit is contained in:
Iván Ovejero
2025-05-06 11:23:45 +02:00
committed by GitHub
parent ade546fb48
commit 75c1a4c5b3
3 changed files with 24 additions and 8 deletions

View File

@@ -1,5 +1,6 @@
import { ValidationError } from '@/js-task-runner/errors/validation-error';
import {
NonArrayOfObjectsError,
validateRunForAllItemsOutput,
validateRunForEachItemOutput,
} from '@/js-task-runner/result-validation';
@@ -24,6 +25,13 @@ describe('result validation', () => {
}).not.toThrow();
});
it('should throw a NonArrayOfObjectsError if the output is an array of arrays (empty)', () => {
expect(() => {
// @ts-expect-error Intentionally invalid
validateRunForAllItemsOutput([[]]);
}).toThrowError(NonArrayOfObjectsError);
});
test.each([
['binary', {}],
['pairedItem', {}],

View File

@@ -1,4 +1,4 @@
export function isObject(maybe: unknown): maybe is { [key: string]: unknown } {
export function isObject(maybe: unknown): maybe is object {
return (
typeof maybe === 'object' && maybe !== null && !Array.isArray(maybe) && !(maybe instanceof Date)
);

View File

@@ -50,20 +50,26 @@ function validateItem({ json, binary }: INodeExecutionData, itemIndex: number) {
}
}
export class NonArrayOfObjectsError extends ValidationError {
constructor() {
super({
message: "Code doesn't return items properly",
description: 'Please return an array of objects, one for each item you would like to output.',
});
}
}
/**
* Validates the output of a code node in 'Run for All Items' mode.
*/
export function validateRunForAllItemsOutput(
executionResult: INodeExecutionData | INodeExecutionData[] | undefined,
) {
if (typeof executionResult !== 'object') {
throw new ValidationError({
message: "Code doesn't return items properly",
description: 'Please return an array of objects, one for each item you would like to output.',
});
}
if (Array.isArray(executionResult)) {
for (const item of executionResult) {
if (!isObject(item)) throw new NonArrayOfObjectsError();
}
/**
* If at least one top-level key is an n8n item key (`json`, `binary`, etc.),
* then require all item keys to be an n8n item key.
@@ -81,6 +87,8 @@ export function validateRunForAllItemsOutput(
validateTopLevelKeys(item, index);
}
}
} else if (!isObject(executionResult)) {
throw new NonArrayOfObjectsError();
}
const returnData = normalizeItems(executionResult);