Agent skill

N8n Expression Testing

by proffesor-for-testing in proffesor-for-testing/agentic-qe

n8n expression syntax validation, context-aware testing, common pitfalls detection, and performance optimization.

MITAuto-check passedProductivity & Automation

Install N8n Expression Testing

skills CLI
$ npx skills add proffesor-for-testing/agentic-qe --skill n8n-expression-testing -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install proffesor-for-testing/agentic-qe n8n-expression-testing --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/proffesor-for-testing/agentic-qe.git skills-src && mkdir -p .claude/skills && cp -r skills-src/assets/skills/n8n-expression-testing .claude/skills/n8n-expression-testing && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
n8n-expression-testing
GitHub stars
494
Token cost
~2.8k tokens
SKILL.md length
268 words
Files
4 (incl. scripts)
Skills in repo
111
Repo updated
First seen
Licence
MIT

At a glance

n8n expression syntax validation, context-aware testing, common pitfalls detection, and performance optimization.

  • Works in 5 steps: VALIDATE syntax before execution → TEST with multiple context scenarios → CHECK for null/undefined handling → …
  • Validating n8n expressions and data transformations
  • SKILL.md covers Quick Reference Card, Expression Syntax Patterns, Validation Patterns and Common Errors and Fixes, plus 6 more sections
  • Tasks that involve Workflow automation

What it does

N8n Expression Testing is an agent skill from proffesor-for-testing/agentic-qe. n8n expression syntax validation, context-aware testing, common pitfalls detection, and performance optimization. Use when validating n8n expressions and data transformations.

Its SKILL.md is about 2.8k tokens, which your agent loads only when the skill is triggered. The skill folder holds 6 other files, including scripts (for example `evals/n8n-expression-testing.yaml`, `schemas/output.json` and `scripts/validate-config.json`).

It sits in Productivity & Automation, covering Workflow automation, Performance optimization and Data cleaning. It works with n8n. The repository describes itself as: Agentic QE Fleet is an open-source AI-powered QA/QE platform designed for use with Coding Agents (works best with Claude Code) featuring specialized agents and skills to support… The licence is MIT.

When your agent uses it

  • Validating n8n expressions and data transformations
  • Tasks that involve Workflow automation
  • Tasks that involve Performance optimization

Example prompts

  • “/n8n-expression-testing”

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. VALIDATE syntax before execution
  2. TEST with multiple context scenarios
  3. CHECK for null/undefined handling
  4. VERIFY type safety
  5. SCAN for security vulnerabilities

What it can do on your machine

Read from SKILL.md and the folder at commit 829d030. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 1 file in scripts/, which the agent can run.

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

N8n Expression Testing loads about 2.8k tokens when it runs. Until then it costs about 50 tokens; SKILL.md has 268 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~50
When it runs · the whole SKILL.md, loaded when a task matches
~2.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from proffesor-for-testing/agentic-qe at commit 829d030, republished under its MIT licence (© proffesor-for-testing). 268 words, ~2,805 tokens.

Download SKILL.mdSave it as .claude/skills/n8n-expression-testing/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.
name
n8n-expression-testing
description
n8n expression syntax validation, context-aware testing, common pitfalls detection, and performance optimization. Use when validating n8n expressions and data transformations.
category
n8n-testing
priority
high
tokenEstimate
1000
agents
n8n-expression-validator
implementation_status
production
optimization_version
1
last_optimized
2025-12-15
quick_reference_card
true
tags
n8n, expressions, javascript, data-transformation, validation
trust_tier
3

n8n Expression Testing

<default_to_action> When testing n8n expressions:

  1. VALIDATE syntax before execution
  2. TEST with multiple context scenarios
  3. CHECK for null/undefined handling
  4. VERIFY type safety
  5. SCAN for security vulnerabilities

Quick Expression Checklist:

  • Valid JavaScript syntax
  • Context variables properly referenced ($json, $node)
  • Null-safe access patterns (?., ??)
  • No dangerous functions (eval, Function)
  • Efficient for large data sets

Common Pitfalls:

  • Accessing nested properties without null checks
  • Type coercion issues
  • Missing fallback values
  • Inefficient array operations </default_to_action>

Quick Reference Card

n8n Expression Syntax
PatternExampleDescription
Basic access{{ $json.field }}Access JSON field
Nested access{{ $json.user.email }}Access nested property
Array access{{ $json.items[0] }}Access array element
Node reference{{ $node["Name"].json.id }}Access other node's data
Method call{{ $json.name.toLowerCase() }}Call string method
Conditional{{ $json.x ? "yes" : "no" }}Ternary expression
Context Variables
VariableDescriptionExample
$jsonCurrent item data{{ $json.email }}
$node["Name"]Other node's data{{ $node["HTTP"].json.body }}
$items()Multiple items{{ $items("Node", 0, 0).json }}
$nowCurrent timestamp{{ $now.toISO() }}
$todayToday's date{{ $today }}
$runIndexRun iteration{{ $runIndex }}
$workflowWorkflow info{{ $workflow.name }}

Expression Syntax Patterns

Safe Data Access
javascript
// BAD: Can fail if nested objects are null
{{ $json.user.profile.email }}

// GOOD: Optional chaining with fallback
{{ $json.user?.profile?.email ?? '' }}

// BAD: Array access without bounds check
{{ $json.items[0].name }}

// GOOD: Safe array access
{{ $json.items?.[0]?.name ?? 'No items' }}
Type Conversions
javascript
// String to Number
{{ parseInt($json.quantity, 10) }}
{{ parseFloat($json.price) }}
{{ Number($json.value) }}

// Number to String
{{ String($json.id) }}
{{ $json.amount.toString() }}
{{ $json.count.toFixed(2) }}

// Date handling
{{ new Date($json.timestamp).toISOString() }}
{{ DateTime.fromISO($json.date).toFormat('yyyy-MM-dd') }}

// Boolean conversion
{{ Boolean($json.active) }}
{{ $json.enabled === 'true' }}
String Operations
javascript
// Case conversion
{{ $json.name.toLowerCase() }}
{{ $json.name.toUpperCase() }}
{{ $json.name.charAt(0).toUpperCase() + $json.name.slice(1) }}

// String manipulation
{{ $json.text.trim() }}
{{ $json.text.replace(/\s+/g, ' ') }}
{{ $json.text.substring(0, 100) }}

// Template strings
{{ `Hello, ${$json.firstName} ${$json.lastName}!` }}
{{ `Order #${$json.orderId} - ${$json.status}` }}
Array Operations
javascript
// Mapping
{{ $json.items.map(item => item.name) }}
{{ $json.items.map(item => ({ id: item.id, total: item.price * item.qty })) }}

// Filtering
{{ $json.items.filter(item => item.active) }}
{{ $json.items.filter(item => item.price > 100) }}

// Reducing
{{ $json.items.reduce((sum, item) => sum + item.price, 0) }}
{{ $json.items.reduce((acc, item) => ({ ...acc, [item.id]: item }), {}) }}

// Finding
{{ $json.items.find(item => item.id === $json.targetId) }}
{{ $json.items.findIndex(item => item.name === 'target') }}

// Joining
{{ $json.tags.join(', ') }}
{{ $json.items.map(i => i.name).join(' | ') }}

Validation Patterns

typescript
// Validate expression syntax
function validateExpressionSyntax(expression: string): ValidationResult {
  // Remove n8n template markers
  const code = expression.replace(/\{\{|\}\}/g, '').trim();

  try {
    // Check if valid JavaScript
    new Function(`return (${code})`);
    return { valid: true };
  } catch (error) {
    return {
      valid: false,
      error: error.message,
      suggestion: suggestFix(error.message, code)
    };
  }
}

// Validate context variables
function validateContextVariables(expression: string): string[] {
  const contextVars = ['$json', '$node', '$items', '$now', '$today', '$runIndex', '$workflow'];
  const usedVars = [];
  const invalidVars = [];

  // Find all $ prefixed variables
  const varPattern = /\$\w+/g;
  let match;

  while ((match = varPattern.exec(expression)) !== null) {
    const varName = match[0];
    if (contextVars.some(cv => varName.startsWith(cv))) {
      usedVars.push(varName);
    } else {
      invalidVars.push(varName);
    }
  }

  return { usedVars, invalidVars };
}

// Test expression with sample data
function testExpression(expression: string, context: any): TestResult {
  const code = expression.replace(/\{\{|\}\}/g, '').trim();

  try {
    // Create function with context
    const fn = new Function('$json', '$node', '$items', '$now', '$today',
      `return (${code})`);

    const result = fn(
      context.$json || {},
      context.$node || {},
      context.$items || (() => ({})),
      context.$now || new Date(),
      context.$today || new Date()
    );

    return { success: true, result };
  } catch (error) {
    return { success: false, error: error.message };
  }
}

Common Errors and Fixes

Undefined Property Access
javascript
// ERROR: Cannot read property 'email' of undefined
{{ $json.user.email }}

// FIX 1: Optional chaining
{{ $json.user?.email }}

// FIX 2: With fallback
{{ $json.user?.email ?? 'no-email@example.com' }}

// FIX 3: Conditional
{{ $json.user ? $json.user.email : '' }}
Type Errors
javascript
// ERROR: toLowerCase is not a function (when null)
{{ $json.name.toLowerCase() }}

// FIX: Null check first
{{ $json.name?.toLowerCase() ?? '' }}

// ERROR: toFixed is not a function (string instead of number)
{{ $json.price.toFixed(2) }}

// FIX: Parse as number first
{{ parseFloat($json.price).toFixed(2) }}

// ERROR: map is not a function (not an array)
{{ $json.items.map(i => i.name) }}

// FIX: Ensure array
{{ (Array.isArray($json.items) ? $json.items : []).map(i => i.name) }}
Node Reference Errors
javascript
// ERROR: Node "Previous Node" not found
{{ $node["Previous Node"].json.data }}

// FIX: Use exact node name (case-sensitive)
{{ $node["Previous Node1"].json.data }}

// FIX: Add fallback for safety
{{ $node["Previous Node"]?.json?.data ?? {} }}

Security Patterns

Dangerous Functions to Avoid
javascript
// DANGEROUS: Never use eval
{{ eval($json.code) }}

// DANGEROUS: Dynamic function creation
{{ new Function($json.code)() }}

// DANGEROUS: setTimeout with string
{{ setTimeout($json.code, 1000) }}

// SAFE: Use explicit operations instead
{{ $json.value * 2 }}
{{ JSON.parse($json.jsonString) }}
Input Validation
javascript
// Validate email format
{{ /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test($json.email) ? $json.email : '' }}

// Sanitize for HTML (basic)
{{ $json.text.replace(/[<>&"']/g, c => ({
  '<': '&lt;', '>': '&gt;', '&': '&amp;', '"': '&quot;', "'": '&#39;'
}[c])) }}

// Limit string length
{{ $json.input.substring(0, 1000) }}

// Validate number range
{{ Math.min(Math.max(parseInt($json.value), 0), 100) }}

Performance Optimization

Efficient Array Operations
javascript
// SLOW: Multiple iterations
{{ $json.items.filter(i => i.active).map(i => i.name).join(', ') }}

// FASTER: Single reduce
{{ $json.items.reduce((acc, i) => i.active ? (acc ? `${acc}, ${i.name}` : i.name) : acc, '') }}

// SLOW: Nested loops
{{ $json.items.map(i => $json.categories.find(c => c.id === i.categoryId)) }}

// FASTER: Create lookup map first (in Code node)
const categoryMap = Object.fromEntries($json.categories.map(c => [c.id, c]));
return $json.items.map(i => categoryMap[i.categoryId]);
Avoid in Expressions
javascript
// AVOID: Complex logic in expressions
{{ $json.items.reduce((acc, item) => {
  const category = $json.categories.find(c => c.id === item.catId);
  if (category && category.active) {
    acc.push({ ...item, categoryName: category.name });
  }
  return acc;
}, []) }}

// BETTER: Move to Code node for complex transformations

Testing Patterns

typescript
// Expression test suite
const expressionTests = [
  {
    name: 'Basic property access',
    expression: '{{ $json.name }}',
    context: { $json: { name: 'John' } },
    expected: 'John'
  },
  {
    name: 'Nested with optional chaining',
    expression: '{{ $json.user?.email ?? "default" }}',
    context: { $json: { user: null } },
    expected: 'default'
  },
  {
    name: 'Array mapping',
    expression: '{{ $json.items.map(i => i.id).join(",") }}',
    context: { $json: { items: [{ id: 1 }, { id: 2 }] } },
    expected: '1,2'
  },
  {
    name: 'Conditional expression',
    expression: '{{ $json.score >= 70 ? "Pass" : "Fail" }}',
    context: { $json: { score: 85 } },
    expected: 'Pass'
  },
  {
    name: 'Node reference',
    expression: '{{ $node["Previous"].json.result }}',
    context: { $node: { Previous: { json: { result: 'success' } } } },
    expected: 'success'
  }
];

// Run tests
for (const test of expressionTests) {
  const result = testExpression(test.expression, test.context);
  console.log(`${test.name}: ${result.result === test.expected ? 'PASS' : 'FAIL'}`);
}

Agent Coordination

Memory Namespace
aqe/n8n/expressions/
├── validations/*    - Expression validation results
├── patterns/*       - Discovered expression patterns
├── errors/*         - Common error catalog
└── optimizations/*  - Performance suggestions
Fleet Coordination
typescript
// Coordinate expression validation with workflow testing
await Task("Validate expressions", {
  workflowId: "wf-123",
  validateAll: true,
  testWithSampleData: true
}, "n8n-expression-validator");


Remember

n8n expressions are JavaScript-like with special context variables ($json, $node, etc.). Testing requires:

  • Syntax validation
  • Context variable verification
  • Null safety checks
  • Type compatibility
  • Security scanning

Key patterns: Use optional chaining (?.) and nullish coalescing (??) for safety. Move complex logic to Code nodes. Always test with edge cases (null, undefined, empty arrays).

© proffesor-for-testing, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 3 other files (scripts) in assets/skills/n8n-expression-testing of proffesor-for-testing/agentic-qe.

  • SKILL.md
  • evals/n8n-expression-testing.yaml
  • schemas/output.json
  • scripts/validate-config.json

Open the folder on GitHubat commit 829d030

Compare with similar skills

N8n Expression Testing next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

N8n Expression Testing compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
N8n Expression Testing this skillproffesor-for-testing/agentic-qe494—~2.8kAutomated safety check: PassMIT
N8n Add Workflowkhanhduyvt0101/workflows110—~1.3kAutomated safety check: PassNone
Airtable Automationclaude-office-skills/skills498—~2.7kAutomated safety check: PassMIT
N8n MCP Tools Expertdavila7/claude-code-templates32k8 repos~3.2kAutomated safety check: PassMIT
Automation InstructionsdeusXmachina-dev/memorylane121—~1.1kAutomated safety check: PassGPL-3.0
n8n Expression Syntaxczlonkowski/n8n-skills6.4k—~5.2kAutomated safety check: PassMIT

Similar skills

  • N8n Add Workflow

    khanhduyvt0101/workflows

    Add a new n8n workflow template to the repository. An agent skill from khanhduyvt0101/workflows.

    110 GitHub stars~1.3k tokensUpdated 4 mo ago
    Productivity & AutomationAuto-check passed
  • Airtable Automation

    claude-office-skills/skills

    Airtable database automation - views, automations, integrations, and workflow triggers

    498 GitHub stars~2.7k tokensUpdated 8 mo ago
    Productivity & AutomationAuto-check passed
  • N8n MCP Tools Expert

    davila7/claude-code-templates

    Expert guide for using n8n-mcp MCP tools effectively. An agent skill from davila7/claude-code-templates.

    32k GitHub starsUsed in 8 repos~3.2k tokens
    Productivity & AutomationAuto-check passed
  • Automation Instructions

    deusXmachina-dev/memorylane

    Write step-by-step automation instructions for a workflow, tailored to your tool (Claude, n8n or Zapier).

    121 GitHub stars~1.1k tokensUpdated yesterday
    Productivity & AutomationAuto-check passed
  • n8n Expression Syntax

    czlonkowski/n8n-skills

    Validates and fixes n8n's double-curly-brace expressions, covering $json, $node, and the webhook body-wrapping mistake.

    6.4k GitHub stars~5.2k tokensUpdated 21 days ago
    Productivity & AutomationAuto-check passed
  • N8n Code Javascript

    davila7/claude-code-templates

    Write JavaScript code in n8n Code nodes. An agent skill from davila7/claude-code-templates.

    32k GitHub starsUsed in 4 repos~4k tokens
    Productivity & AutomationAuto-check passed

More from proffesor-for-testing/agentic-qe

All 111 skills in this repo
  • Contract Testing

    proffesor-for-testing/agentic-qe

    Consumer-driven contract testing for microservices using Pact, schema validation, API versioning, and backward compatibility testing.

    494 GitHub stars~1.8k tokensUpdated 3 days ago
    Auto-check passed
  • Mutation Testing

    proffesor-for-testing/agentic-qe

    Test quality validation through mutation testing, assessing test suite effectiveness by introducing code mutations and measuring kill rate.

    494 GitHub stars~1.7k tokensUpdated 3 days ago
    Auto-check passed
  • Performance Testing

    proffesor-for-testing/agentic-qe

    Profiles application performance under load using k6, Artillery, or JMeter to measure latency, throughput, and error rates.

    494 GitHub stars~2.4k tokensUpdated 3 days ago
    Auto-check passed
  • Code Review Quality

    proffesor-for-testing/agentic-qe

    Conduct context-driven code reviews focusing on quality, testability, and maintainability.

    494 GitHub starsUsed in 1 repo~1.9k tokens
    Auto-check passed
  • Security Testing

    proffesor-for-testing/agentic-qe

    Scans for security vulnerabilities including XSS, SQL injection, CSRF, and auth flaws using OWASP Top 10 methodology.

    494 GitHub stars~2.7k tokensUpdated 3 days ago
    Auto-check: notes
  • Database Testing

    proffesor-for-testing/agentic-qe

    Database schema validation, data integrity testing, migration testing, transaction isolation, and query performance.

    494 GitHub starsUsed in 1 repo~1.7k tokens
    Auto-check passed

Works with

Questions about N8n Expression Testing

What does N8n Expression Testing do?

n8n expression syntax validation, context-aware testing, common pitfalls detection, and performance optimization. N8n Expression Testing is an agent skill from proffesor-for-testing/agentic-qe. n8n expression syntax validation, context-aware testing, common pitfalls detection, and performance optimization.

When should I use N8n Expression Testing?

N8n Expression Testing fits situations like: validating n8n expressions and data transformations; tasks that involve Workflow automation; tasks that involve Performance optimization.

How do I install N8n Expression Testing in Claude Code?

Run `npx skills add proffesor-for-testing/agentic-qe --skill n8n-expression-testing -a claude-code`. Or copy the skill folder (assets/skills/n8n-expression-testing in proffesor-for-testing/agentic-qe) into .claude/skills/n8n-expression-testing in your project. Claude Code loads it when a task matches its description.

How do I install N8n Expression Testing in Codex?

Run `npx skills add proffesor-for-testing/agentic-qe --skill n8n-expression-testing -a codex`. Or copy the skill folder (assets/skills/n8n-expression-testing in proffesor-for-testing/agentic-qe) into .agents/skills/n8n-expression-testing in your project. Codex loads it when a task matches its description.

Can I use N8n Expression Testing in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add proffesor-for-testing/agentic-qe --skill n8n-expression-testing -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/n8n-expression-testing, .gemini/skills/n8n-expression-testing, .github/skills/n8n-expression-testing and .opencode/skills/n8n-expression-testing in your project.

What does N8n Expression Testing need to run?

SKILL.md names no scripts, command-line tools or credentials: N8n Expression Testing is instructions for the agent only.

Does N8n Expression Testing access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is N8n Expression Testing safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does N8n Expression Testing use?

N8n Expression Testing is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does N8n Expression Testing use?

About 2.8k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to N8n Expression Testing?

Skills that share tags, products or a category with N8n Expression Testing: N8n Add Workflow (khanhduyvt0101/workflows, 110 stars), Airtable Automation (claude-office-skills/skills, 498 stars), N8n MCP Tools Expert (davila7/claude-code-templates, 32k stars) and Automation Instructions (deusXmachina-dev/memorylane, 121 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains N8n Expression Testing?

proffesor-for-testing (a GitHub user) maintains it in proffesor-for-testing/agentic-qe, which has 494 GitHub stars. The repository holds 111 skills in this directory. The repository was last updated on October 4, 2026.

Source: proffesor-for-testing/agentic-qe on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.