Code Node
What Code is and why it exists
Code is the precision node for workflow logic that cannot be expressed cleanly with static field configuration. Use it for deterministic transforms, contract validation, mapping adapters, and bounded helper computations.
In NodeFox, Code extends graph orchestration; it should not replace it. When Code grows into a hidden mini-service, branch explainability and replay quality degrade quickly.
Runtime behavior
Code executes in a sandboxed worker environment with explicit runtime primitives. It receives slot inputs, processes logic, and emits slot outputs back into graph routing.
Code slot indexing is explicit and should be treated as a hard rule:
- builder/UI slot references are human-facing and 1-based (
$1to$8) - code APIs are 0-based (
inputs.get(0)is slot 1,inputs.get(1)is slot 2,outputs.set(0, value)writes slot 1)
Keep this mapping documented in-team to avoid off-by-one bugs during transforms and routing.
Code can transform, validate, and enrich data. High-impact side effects should still be routed through Writer branches so activation and audit controls stay explicit.
Runtime objects and what they do
| Object | Purpose | Practical guidance |
|---|---|---|
inputs | Read input slots | Validate shape before access and guard missing/nullable fields. |
outputs | Write output slots | Emit typed, predictable contracts for downstream nodes. |
session | Per-run key/value state | Useful for bounded retries and per-run memory, but avoid overloading as hidden global logic. |
files | File helper access | Restrict file side effects to clear branches and enforce path conventions. |
utils | Shared helper functions | Keep helper behavior deterministic and side-effect free where possible. |
nodefox | Runtime/workspace helpers | Use for platform-aware metadata and controlled workspace operations. |
UI | App-facing rendering/update hooks | Keep UI concerns separate from governance/policy decisions. |
fetch | Outbound HTTP in permitted contexts | Bound by policy and domain allow-lists when enabled. |
console | Run-level logging | Never log secrets, tokens, or sensitive payload fields. |
Core configuration fields
| Field | What it controls | Practical guidance |
|---|---|---|
Script | JS/TS logic body | Keep scripts short and testable; avoid monolithic code nodes. |
Can Use Fetch | Outbound HTTP capability | Enable only when needed; pair with strict domain and credential controls. |
Input Labels / Output Labels | Slot intent documentation | Label critical slots to keep branch contracts legible in review. |
Optional / Keep / Delay / Activated | Execution gate behavior | Use deliberately; these flags are control semantics, not convenience toggles. |
Architecture patterns that scale
Reader -> Code(normalize contract) -> Data -> DecisionConversation(schema) -> Code(strict validation) -> Decision(policy)Data(For) -> Code(per-item transform) -> Buffer(Stack)Decision -> Code(low-risk formatting) -> Writer(Activated)
These patterns keep Code narrow while preserving graph-level observability and deterministic branch intent.
Reliability checklist for Code nodes
- Validate every inbound field that affects routing or side effects.
- Emit explicit error classes (
validation_error,dependency_error,transient_error) to downstream Decision branches. - Keep external calls bounded with timeout and retry budget.
- Ensure outputs match schema expectations for downstream Data/Decision nodes.
- Prefer pure transforms where possible; isolate side effects elsewhere.
Common failure modes
- Monolithic scripts that mix transform, routing, and side effects:
- split into multiple nodes with clear responsibility.
- Silent shape drift in outputs:
- add strict validation and branch explicit failure paths.
- Hidden retry loops:
- keep retry/termination policy in Decision, not ad hoc script recursion.
- Credential or secret leakage in logs:
- scrub logs and avoid printing raw request/response bodies.
If a Code node is hard to explain in one short paragraph, split it into smaller explicit stages.