Code node
The Code node in full — the fields it reads and writes, the async main function it runs, the runtime environment, environment variables and secrets, the editing check cases, and the run-time limits and failures.
The Code node runs Python you write once per item in an isolated sandbox to reshape fields, compute values, or call an external service. It reads the input fields you declare and writes the output fields you declare. It is one of the nodes you add between the pipeline’s Start and End. See the pipeline nodes overview for how it fits with the others.
Everything on this node can be set two ways: ask the agent, or open the node and edit by hand. By hand, the Python lives in the Code card, the input and output fields in their lists, the environment variables in the Environment variables card, and the check cases in the checks section.
Input and output fields
Section titled “Input and output fields”You declare each field the node reads and each field it writes, with a name and a type. A node may declare any number of input and output fields, and each is either required or optional. A field name must:
- start with a letter and end with a letter or digit,
- contain only lowercase letters, digits, and underscores,
- be at most 128 characters,
- be unique across the pipeline.
Your code receives the input fields as one dictionary keyed by field name and must return a dictionary keyed by the output field names. An optional input with no value for the current item is absent from the input dictionary. An optional output may be left out of the returned dictionary.
After the code runs, the item fails if a required output field is missing, if the returned dictionary contains a field you did not declare, or if a returned value does not match its field’s declared type.
The code
Section titled “The code”The code is an async function named main that the platform calls once per item with that item’s inputs. It takes one argument, the dictionary of input fields, and returns a dictionary of output fields. A new node starts from this skeleton:
from main_types import Inputs, Outputs
async def main(inputs: Inputs) -> Outputs: return {}A node that reads an input field review_text and writes an output field word_count looks like this:
from main_types import Inputs, Outputs
async def main(inputs: Inputs) -> Outputs: return {"word_count": len(inputs["review_text"].split())}The code must:
- import
InputsandOutputsfrommain_types, - define a top-level function named
main, markedasync, - give
mainexactly one argument annotatedInputsand annotate its return asOutputs, - contain at least one
returnthat returns a value, - be valid, non-empty Python.
If the code raises, the item fails and the Python error, with its traceback, is recorded as the item’s failure reason. Every returned value must survive JSON encoding: text, numbers, true/false, lists, and dictionaries do. A date or file object does not, and returning one fails the item. Return a dictionary. If the code returns anything else:
- a check case rejects any such run;
- at run time a returned number or boolean yields no output fields, so the item fails whenever the node declares a required output;
- a returned list or string fails the item even when every output is optional, because its entries are read as field names the node does not have.
Runtime environment
Section titled “Runtime environment”The platform pins the runtime to Python 3.12 and installs nothing on top. The standard library is available. Whatever else the base runtime happens to contain is not part of the contract, so rely only on the standard library. The node has no option to add packages, and an import of a package that is not present raises, which fails the item. Each item runs on its own. Nothing the code stores during one item’s run is available to another.
Environment variables
Section titled “Environment variables”Environment variables are name–value pairs passed to your code as operating-system environment variables, such as an API key a call to an external service needs. Each entry is set either to a fixed text value or to a secret saved in the project, so a credential stays out of the code. An entry’s name must:
- contain only uppercase letters, digits, and underscores, and not start with a digit,
- be unique within the node.
An entry set to a secret must name a secret that exists in the project. You create those secrets on the project’s Secrets page. The agent can list their names to reference here but cannot create one. An invalid or duplicate name, or a reference to a secret the project does not have, is a configuration error that blocks the deploy.
The check
Section titled “The check”The check, the Code Test card on the node, is a set of check cases you define while editing. Each case has a name and its own sample values for the input fields, and running it executes the code once against those samples and reports success or the error it produced. You may define any number of cases.
A case’s run has the same 60-second and 10 MB ceilings as a run-time item, plus a stricter cap of its own: each sample input value and each value the case’s run returns is capped at 32 KB. Code whose fields approach the 1 MB run-time cap therefore cannot be exercised at full size in a case.
Running the cases is not required to deploy. A node with no cases, or with a case that has not been run or is still running, gets a warning you can override at deploy. Any case that failed blocks the deploy, as does leaving the code empty.
Limits
Section titled “Limits”| What | Ceiling | Over the limit |
|---|---|---|
| Run time per item | 60 seconds | Item fails |
| Combined input fields | 10 MB | The attempt errors out and retries, rather than recording a per-item failure reason |
| Returned output as a whole | 10 MB | Item fails |
| A single returned field | 1 MB | Item fails |
| Code text | 150,000 characters | Configuration error, blocks the deploy |
| Environment variables, all names and values combined | 150,000 characters | Configuration error, blocks the deploy |
The run-time ceilings apply to every item, whether or not the node’s check cases passed. Sizes are measured on the JSON text of the values, in binary units (1 MB = 1,024 × 1,024 bytes). The whole-output cap counts a few bytes of packaging around the returned dictionary, so the usable budget sits just under 10 MB.
The 60-second timer stops code that is waiting on the network, on a subprocess, or on anything awaited. Code stuck in a blocking computation can run past it. The platform then cuts the run at an outer deadline about 30 seconds later and fails the item.
Related
Section titled “Related”- Pipeline nodes — how the Code node fits with the other node kinds
- Fields and data — field names, types, and how values are shaped
- Match node — route each item on a value your code derives
- Self-check — where check results land in the deploy gate
- Glossary — secret, field, and node defined briefly