Digital Automation · Focus area 2: Code inside the workflow

DA5: Code inside the workflow

Goal: write short JavaScript and Python steps inside a workflow when ready-made nodes can't do the job: knowing when code is the right choice, reading items in and returning items out, common transformations, and testing code so others can trust it.

You'll need: your n8n set-up, the Sharma Textiles order workflow and the cleaned data from DA4, and the JavaScript you learned in Level 3.

Time: reading about 2 hours · practice (the Try it tasks) about 3 hours · assignment about 3 to 4 hours.

Where this is used: most real workflows have one or two small code steps: grouping orders by customer, building a message from many fields, or checking a value against a rule. Knowing a little code lets an automation builder finish jobs that would otherwise need a developer.

How it differs: an app developer writes whole programs. A code step in a workflow is usually five to forty lines that take items in and hand items on. The skill is keeping it small, readable and tested, so the visual workflow still explains itself.

Lessons

  1. 1When a ready-made step isn't enoughReading 15–25 minutes, plus practice✓
  2. 2The Code node in JavaScriptReading 15–25 minutes, plus practice✓
  3. 3Python in the workflowReading 15–25 minutes, plus practice✓
  4. 4Common transformationsReading 15–25 minutes, plus practice✓
  5. 5Testing and keeping code safeReading 15–25 minutes, plus practice✓

🛠️Assignment: Code steps for Sharma Textiles

This adds the code steps used by the weekly CRM tidy-up and the payment workflow projects.

  1. Find one place in your order workflow where a Code node is clearer than a chain of nodes, and write down why.
  2. Build the daily owner summary in a JavaScript Code node: order count, revenue in rupees and the top three products.
  3. Write the order count and total step in Python too, and confirm both versions give the same result.
  4. Build the CRM deduplication step with a written "which record wins" rule and a before-and-after report.
  5. Write and run a test table of at least five cases, including an empty input, a missing field and a duplicate.

Self-check before you finish:

✅Module check

Explain in a few sentences, in your own words:

When and how should an automation builder use code inside a workflow?

Show a good answer

A good answer mentions: preferring ready-made nodes and expressions when they fit, and using a Code node when logic would need a long chain of nodes or must look across all items; returning an array of { json } items and choosing "all items" or "each item" mode; choosing JavaScript or Python by what the platform supports and who maintains it, with heavy work moved to a separate service; the common patterns of filter, map, group, deduplicate and look up, with a written rule for which record wins; and testing with pinned awkward cases, failing loudly on bad input, and keeping secrets in credentials.

📚Official references

Official documentation and guidance for this module's topics, chosen on 2 November 2026. Tools, laws and standards change, so check the current version before you rely on a detail. If a link has moved, search the same site.

📝Module quiz

10 questions · 10 marks each · 100 marks in all · pass mark 70% · retry as often as you like ·

1. A support workflow uses eleven IF nodes in a row to route emails by keyword, and the team can no longer follow it. What's the better design?

Why each option is right or wrong

  • “Add a twelfth IF node for the newest keyword” (Incorrect): That makes the chain longer and harder to follow.
  • “Split it into eleven separate workflows” (Incorrect): Eleven workflows would be harder to maintain than one chain.
  • “Send every email to one shared inbox instead” (Incorrect): That removes the routing the business asked for.
  • “A keyword table in one Code node” is correct.

    A small table of keywords and teams is easier to read and update than a long chain of branches. The Code node returns a team field, and one Switch node sends each email to the right place. Adding a keyword now means editing one table.

    • Name it: "Pick team from keywords".
    • Test: one email per team, plus one that matches nothing.

📖 Revise: Lesson 1: When a ready-made step isn't enough

Question ID sp-digital-automation-05-q1 · Report a mistake in this question
2. A Code node runs without errors, but the next node receives no data. The code ends with return { json: summary };. What's wrong?

Why each option is right or wrong

  • “The Code node is in the wrong mode” (Incorrect): Either mode expects items to be returned as a list, so changing mode alone won't help.
  • “The summary variable is too large to pass on” (Incorrect): A summary of a day's orders is small; size isn't the problem.
  • “The next node needs its credentials refreshed” (Incorrect): The next node receives nothing at all, which points to the Code node's output, not credentials.
  • “It returns an object, not an array of items” is correct.

    n8n expects a list of items from a Code node, each shaped like { json: ... }. Wrapping the result in square brackets, return [{ json: summary }];, passes the summary on as one item.

    • Pin data: so the next edit can be checked in seconds.
    • Look at: the node's output panel after each change.

📖 Revise: Lesson 2: The Code node in JavaScript

Question ID sp-digital-automation-05-q2 · Report a mistake in this question
3. You need the top three products across all of today's orders. Which Code node set-up fits?

Why each option is right or wrong

  • “Run Once for Each Item, reading $json” (Incorrect): Each run would see only one order, so it can't compare products across orders.
  • “An expression in the message field” (Incorrect): An expression works on one item at a time and can't look across all items.
  • “A Set node that adds a rank field” (Incorrect): A Set node can't compare items to work out a ranking.
  • “Run Once for All Items, reading $input.all()” is correct.

    Finding the top products means comparing every order at once. In "all items" mode the code runs once, sees the full list, groups quantities by product and returns one summary item.

    • Then: sort by quantity and keep the first three.
    • Return: a single item with the summary message.

📖 Revise: Lesson 2: The Code node in JavaScript

Question ID sp-digital-automation-05-q3 · Report a mistake in this question
4. A weekly GST step looks up a rate for each product family with rates.get(family, 0). A new family "KUR" (kurtas) has just been added to the shop. What happens, and what should change?

Why each option is right or wrong

  • “Nothing; zero is a safe default for unknown products” (Incorrect): Zero isn't safe here: it would under-report tax on every kurta sold.
  • “The step crashes, so add a try-except that skips the line” (Incorrect): The current code doesn't crash; it uses 0. Skipping the line would also lose sales from the report.
  • “Kurtas get the highest rate; lower the default” (Incorrect): The default is 0, not the highest rate, and any guessed default can still be wrong.
  • “Taxed at 0%; error on unknown families” is correct.

    The default of 0 quietly treats any new family as tax-free. Raising an error with the SKU stops the run and asks for the right rate, so a person adds "KUR" to the table before the report goes out.

    • Owner of the table: the accountant.
    • Test: run with a made-up family on purpose.

📖 Revise: Lesson 3: Python in the workflow

Question ID sp-digital-automation-05-q4 · Report a mistake in this question
5. A Python Code node that imports a data library works on your self-hosted n8n but fails on the client's cloud instance. The step handles about 300 rows a day. What's the sensible fix?

Why each option is right or wrong

  • “Move the client to self-hosting to get the library” (Incorrect): Changing the whole hosting set-up for one library is a large change for a small step.
  • “Copy the library's code into the node” (Incorrect): That makes the step long, hard to maintain and possibly against the library's licence.
  • “Switch the node to JavaScript without changing the code” (Incorrect): Python code won't run as JavaScript; it would need rewriting anyway.
  • “Rewrite the step with built-in Python only” is correct.

    The client's instance doesn't offer that library. Built-in Python handles 300 rows a day easily, so rewriting the step removes the dependency. Noting which libraries a step needs prevents the same surprise later.

    • Check: what the target instance supports before building.
    • For heavy work: a separate Python service instead.

📖 Revise: Lesson 3: Python in the workflow

Question ID sp-digital-automation-05-q5 · Report a mistake in this question
6. Sharma Textiles' accountant knows Python but not JavaScript, and will maintain the weekly tax summary step. The platform supports both. Which language should the step use?

Why each option is right or wrong

  • “JavaScript, because it is n8n's main language” (Incorrect): Being common on the platform matters less than who maintains the step.
  • “Whichever is shorter for this task” (Incorrect): A few lines' difference matters less than whether the maintainer can read it.
  • “Both, in two parallel nodes, to compare results” (Incorrect): Running two versions forever doubles the maintenance work.
  • “Python, so the person maintaining it can read it” is correct.

    Both languages can do this job here. The step will be changed by the accountant, so writing it in the language they read keeps it maintainable after you hand it over.

    • Still check: that the instance runs Python steps well.
    • Add comments: for each tax rule they gave you.

📖 Revise: Lesson 3: Python in the workflow

Question ID sp-digital-automation-05-q6 · Report a mistake in this question
7. After a deduplication step that keeps the newest record per phone number, a long-standing customer's GST number disappears from the CRM. Why, and what's the fix?

Why each option is right or wrong

  • “The CRM rejected the GST field; check its format rules” (Incorrect): The field was lost before reaching the CRM, in the deduplication step.
  • “Deduplication is too risky; turn the step off” (Incorrect): Duplicates cause real problems; the step needs a better rule, not removal.
  • “Keep the oldest record instead of the newest” (Incorrect): That would lose new details such as an updated address.
  • “The newest record had no GST field; merge field by field” is correct.

    The newest record came from an enquiry form without a GST field, so keeping it whole lost the older value. Merging per field, keeping the newest value but not overwriting a filled field with an empty one, keeps both.

    • Rerun: on a copy first and compare.
    • Write down: the merge rule for the client.

📖 Revise: Lesson 4: Common transformations

Question ID sp-digital-automation-05-q7 · Report a mistake in this question
8. A totals step treats a missing price as 0 with o.price_paise || 0. An order with a missing price goes through. What's the risk?

Why each option is right or wrong

  • “None; the order total will simply show as zero” (Incorrect): A zero total for a real order is exactly the problem: the report and invoices would be wrong.
  • “The workflow will crash on the next node” (Incorrect): || 0 stops a crash; that is why the problem passes unnoticed.
  • “The order will be counted twice” (Incorrect): A missing price affects the amount, not the count.
  • “Quietly wrong totals and possibly free orders” is correct.

    A missing price usually means a data problem upstream. Turning it into 0 hides the problem and lowers revenue figures, and an invoice could go out for nothing. Stopping or flagging the item lets a person fix it.

    • Better: throw an error naming the order and SKU.
    • Or: route the item to a review list.

📖 Revise: Lesson 4: Common transformations

Question ID sp-digital-automation-05-q8 · Report a mistake in this question
9. Testing a CRM clean-up step, you find that contacts without a phone number vanish from the output. No error appears. What should you do?

Why each option is right or wrong

  • “Nothing; contacts without phones can't be messaged anyway” (Incorrect): They may still be real customers with emails and orders. Losing them silently is a data loss.
  • “Give them a placeholder number so they pass through” (Incorrect): A made-up number would pollute the CRM and could be messaged by mistake.
  • “Remove that case from the test table” (Incorrect): Removing the test hides the problem instead of fixing it.
  • “List them in the report and rerun every test” is correct.

    Records that disappear without notice are a silent failure. Adding them to the run's report lets a person decide what to do, and rerunning all tests confirms the fix didn't break anything else.

    • Test row: "contact with no phone: listed in report".
    • Principle: nothing should vanish without a trace.

📖 Revise: Lesson 5: Testing and keeping code safe

Question ID sp-digital-automation-05-q9 · Report a mistake in this question
10. A workflow you inherited has an API key typed directly into a Code node, and the workflow file has been shared with an outside agency. What's the first thing to do?

Why each option is right or wrong

  • “Delete the agency's copy of the file” (Incorrect): You can't be sure every copy is gone, so the key must be treated as exposed.
  • “Rename the variable so the key is less obvious” (Incorrect): The key is still readable in the file; renaming hides nothing.
  • “Ask the agency not to use the key” (Incorrect): A request doesn't protect the account; the key itself needs replacing.
  • “Move it to credentials; replace the key” is correct.

    Anyone with the file can read a key typed into code. Moving it into the credentials store protects it from now on, and replacing (rotating) the key with the provider makes the exposed copy useless.

    • Handover note: code steps read keys from credentials only.
    • Check: other workflows for the same pattern.

📖 Revise: Lesson 5: Testing and keeping code safe

Question ID sp-digital-automation-05-q10 · Report a mistake in this question

ProLearners Assist