Skip to content

Internal JS Task Runner Spawns in External Mode, Causing JavaScript Code Nodes to Fail #22798

Description

@raphaelbahat

Bug Description

When using an external task runner in n8n with the configuration N8N_RUNNERS_MODE=external, an internal "JS Task Runner" automatically spawns despite being configured to use only external runners. This internal runner immediately fails during the task handshake and disconnects, preventing JavaScript Code nodes from executing on the external runner.

Key Issue: The task broker receives execution requests for JavaScript Code nodes, but continuously defers them because the internal runner keeps registering and immediately disconnecting without accepting any tasks. External JavaScript runners register successfully but never receive execution offers because the failing internal runner blocks them.

Native Python Code nodes work correctly when using the same external runner setup, suggesting the issue is specific to JavaScript runner routing.

Also see this thread in the community forum.

To Reproduce

  1. Deploy n8n main with external runners enabled:

    Environment Variables:
    - N8N_RUNNERS_ENABLED=true
    - N8N_RUNNERS_MODE=external
    - N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
    - N8N_RUNNERS_BROKER_PORT=5679
    - N8N_RUNNERS_AUTH_TOKEN=<matching-token>
    - N8N_NATIVE_PYTHON_RUNNER=true
  2. Deploy an external task runner in a separate container:

    Environment Variables:
    - N8N_RUNNERS_TASK_BROKER_URI=http://n8n-main:5679
    - N8N_RUNNERS_AUTH_TOKEN=<matching-token>
  3. Verify runner connectivity:

    • From runner container: getent hosts n8n-main (or broker hostname) resolves correctly

    • Network connectivity is working

  4. Create and execute a workflow:

    • Create a simple workflow with a JavaScript Code node (e.g., return 1 + 1)
    • Enable debug logging on n8n main: N8N_RUNNERS_BROKER_LOG_LEVEL=debug
    • Execute the workflow
    • Expected: JavaScript code executes on the external runner
    • Actual: Execution hangs and eventually times out
  5. Check logs:

    • n8n main container:
    2025-12-04T18:58:57.397Z | debug | Start executing node "Code in JavaScript"
    2025-12-04T18:58:57.399Z | debug | Running node "Code in JavaScript" started
    
    2025-12-04T18:58:57.405Z | debug | Task (Z6hWQY4H) deferred until runner is ready
    2025-12-04T18:58:57.405Z | debug | Deregistered runner "c77264ea7ec05570"
    
    2025-12-04T18:58:58.528Z | info  | Registered runner "JS Task Runner" (y4eZWdMnk9aKVvI76oGa0)  ← Should not spawn
    2025-12-04T18:58:58.539Z | debug | Deregistered runner "y4eZWdMnk9aKVvI76oGa0"  ← Immediate disconnect
    
    2025-12-04T18:59:00.422Z | info  | Registered runner "launcher-javascript" (0da7d8de4a34d173)
    2025-12-04T18:59:00.424Z | debug | Task (4f65LnYa) deferred until runner is ready
    2025-12-04T18:59:00.425Z | debug | Deregistered runner "0da7d8de4a34d173"      ← Immediate disconnect
    
    [Pattern repeats every 2-3 seconds]
    
    • n8n task runner:
    INFO  [launcher:js] Waiting for task broker to be ready...
    INFO  [launcher:js] Waiting for launcher's task offer to be accepted...
    
    [Repeats indefinitely - never receives task offer]
    
    ERROR [runner:js] Task runner failed to start {
      error: Error: getaddrinfo ENOTFOUND hostname
      ...
    }
    
  6. For comparison, create the same workflow but with a Python Code node:

    return 1 + 1
    • This executes successfully on the external runner, proving external runners are functional.

Expected behavior

Expected:

  1. When N8N_RUNNERS_MODE=external is set, only external runners should be registered (launcher-javascript, launcher-python)
  2. No internal "JS Task Runner" should spawn
  3. JavaScript Code nodes should execute on the external launcher-javascript runner
  4. Execution should complete successfully with the correct output
  5. Logs should show:
    info  | Registered runner "launcher-javascript"
    debug | Task (xxx) accepted by runner
    debug | Task (xxx) completed
    

Actual:

  1. Both internal and external JavaScript runners are registered
  2. Internal "JS Task Runner" spawns automatically and immediately disconnects
  3. External runner never receives task execution offers
  4. Tasks remain in "deferred" state indefinitely
  5. Workflow execution times out or fails with no clear error
  6. Python Code nodes work correctly (external runner is functional)

Debug Info

Debug info

core

  • n8nVersion: 1.122.5
  • platform: docker (self-hosted)
  • nodeJsVersion: 22.21.0
  • nodeEnv: production
  • database: postgres
  • executionMode: regular
  • concurrency: -1
  • license: enterprise (production)
  • consumerId: 0ee11057-9aa2-4c41-8084-b4b76d2695f3

storage

  • success: all
  • error: all
  • progress: false
  • manual: true
  • binaryMode: memory

pruning

  • enabled: true
  • maxAge: 336 hours
  • maxCount: 10000 executions

client

  • userAgent: mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/143.0.0.0 safari/537.36
  • isTouchDevice: false

Generated at: 2025-12-05T08:27:03.330Z

Operating System

Linux (containerized environment / Docker)

n8n Version

1.122.5

Node.js Version

22.21.0

Database

PostgreSQL

Execution mode

main (default)

Hosting

self hosted

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions