mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-02-09 06:43:08 +00:00
fix: add validation for resourceLocator properties in AI model nodes
This fixes a critical validation gap where AI agents could create invalid
configurations for nodes using resourceLocator properties (primarily AI model
nodes like OpenAI Chat Model v1.2+, Anthropic, Cohere, etc.).
Before this fix, AI agents could incorrectly pass a string value like:
model: "gpt-4o-mini"
Instead of the required object format:
model: { mode: "list", value: "gpt-4o-mini" }
These invalid configs would pass validation but fail at runtime in n8n.
Changes:
- Added resourceLocator type validation in config-validator.ts (lines 237-274)
- Validates value is an object with required 'mode' and 'value' properties
- Provides helpful error messages with exact fix suggestions
- Added 10 comprehensive test cases (100% passing)
- Updated version to 2.17.3
- Added CHANGELOG entry
Affected nodes: OpenAI Chat Model (v1.2+), Anthropic, Cohere, DeepSeek,
Groq, Mistral, OpenRouter, xAI Grok Chat Models, and embeddings nodes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -234,8 +234,45 @@ export class ConfigValidator {
|
||||
message: `Property '${key}' must be a boolean, got ${typeof value}`,
|
||||
fix: `Change ${key} to true or false`
|
||||
});
|
||||
} else if (prop.type === 'resourceLocator') {
|
||||
// resourceLocator must be an object with mode and value properties
|
||||
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
||||
const fixValue = typeof value === 'string' ? value : JSON.stringify(value);
|
||||
errors.push({
|
||||
type: 'invalid_type',
|
||||
property: key,
|
||||
message: `Property '${key}' is a resourceLocator and must be an object with 'mode' and 'value' properties, got ${typeof value}`,
|
||||
fix: `Change ${key} to { mode: "list", value: ${JSON.stringify(fixValue)} } or { mode: "id", value: ${JSON.stringify(fixValue)} }`
|
||||
});
|
||||
} else {
|
||||
// Check required properties
|
||||
if (!value.mode) {
|
||||
errors.push({
|
||||
type: 'missing_required',
|
||||
property: `${key}.mode`,
|
||||
message: `resourceLocator '${key}' is missing required property 'mode'`,
|
||||
fix: `Add mode property: { mode: "list", value: ${JSON.stringify(value.value || '')} }`
|
||||
});
|
||||
} else if (typeof value.mode !== 'string') {
|
||||
errors.push({
|
||||
type: 'invalid_type',
|
||||
property: `${key}.mode`,
|
||||
message: `resourceLocator '${key}.mode' must be a string, got ${typeof value.mode}`,
|
||||
fix: `Set mode to "list" or "id"`
|
||||
});
|
||||
}
|
||||
|
||||
if (value.value === undefined) {
|
||||
errors.push({
|
||||
type: 'missing_required',
|
||||
property: `${key}.value`,
|
||||
message: `resourceLocator '${key}' is missing required property 'value'`,
|
||||
fix: `Add value property to specify the ${prop.displayName || key}`
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Options validation
|
||||
if (prop.type === 'options' && prop.options) {
|
||||
const validValues = prop.options.map((opt: any) =>
|
||||
|
||||
Reference in New Issue
Block a user