Skip to content

Python code steps: run your own Python inside a flow

A Code step runs a short Python function on the values a flow already holds and writes what it returns back to the flow, so a reshaping, a calculation or a check that no other step does takes a few lines instead of an external service.

The code runs in an isolated sandbox with the common data packages preinstalled and no network access. Each time the step runs it uses one code run from your organisation's licence.

LanguagePython 3.12
NetworkNone
Timeout30 s (up to 120 s)
Cost1 code run per run

When to reach for this

  • Reshape a result. Turn a warehouse query's rows into the totals per region a later step needs.
  • Calculate. A weighted score, a forecast with statsmodels, a statistic with scipy.
  • Check. Validate a payload against a JSON schema and return what is wrong.

If a Transform expression can do it, use that instead: it is free and needs no code. To call an external system, use a Webhook step after the code step, because the code itself cannot reach the network.

Write a code step

Drag Code from the palette's Steps group onto the canvas. The step starts with a working function you edit:

def main(inputs):
    # inputs holds the values listed under "Inputs"
    return {"result": inputs}
Field What it does
Code Python that defines a top-level def main(inputs):. It must return a dict that can be written as JSON.
Inputs Up to 20 rows of name and from. The context key in from reaches main as inputs["name"]. A name is a Python name: letters, digits and _, not starting with a digit.
Output key The context key the returned dict is written to. Later steps read it as {{output_key}}, or as a name in an expression.
Timeout Seconds the code may run, from 1 to 120. Empty means 30.

An example that totals a query result per region:

def main(inputs):
    totals = {}
    for row in inputs["rows"]:
        totals[row["region"]] = totals.get(row["region"], 0) + row["amount"]
    return {"totals": totals, "regions": len(totals)}

With the input rows taken from the query step's output key and the output key by_region, the next step reads by_region["totals"].

Inputs and outputs are JSON. Values arrive as dicts, lists, strings, numbers, booleans and None. The returned dict must be JSON too, with no key starting with _: convert a pandas DataFrame with df.to_dict(orient="records"), and a date with .isoformat(), before you return it.

The editor checks the code as you type. A syntax error, or no main, shows inline, and the version cannot be submitted for review until it is fixed. Importing a networking module (requests, httpx, socket, urllib, aiohttp) shows a hint naming that module: the import works, but no request gets through. The editor says each of these in your own language; only Python's description of a syntax error stays as Python words it.

To try the step, use Run from here in its panel. A test run uses a code run too.

What the code can use

Python 3.12 with about 650 packages preinstalled, among them:

Need Packages
Data frames and arrays pandas 2.2, polars 1.36, numpy 1.26, pyarrow 16
Statistics and models scipy 1.13, scikit-learn 1.5, statsmodels 0.14, sympy, networkx
Files in memory openpyxl, xlrd, lxml, beautifulsoup4
Dates and text python-dateutil, pytz, tzdata, regex
Validation jsonschema, pydantic 2

Not included: duckdb and rapidfuzz. You cannot install packages yourself.

All preinstalled packages
Automat==20.2.0
Babel==2.11.0
Bottleneck==1.3.7
CairoSVG==2.8.2
CoolProp==7.2.0
Deprecated==1.3.1
Django==6.0
Faker==38.2.0
Flask==3.0.3
GitPython==3.1.43
HeapDict==1.0.1
Hypercorn==0.18.0
Jinja2==3.1.4
Kivy==2.3.1
Kivy-Garden==0.1.5
Markdown==3.4.1
MarkupSafe==2.1.3
MouseInfo==0.1.3
Naked==0.1.32
Protego==0.1.16
PyAutoGUI==0.9.54
PyDispatcher==2.0.5
PyGetWindow==0.0.9
PyJWT==2.13.0
PyMsgBox==2.0.1
PyMuPDF==1.26.7
PyPDF2==3.0.1
PyQt5==5.15.10
PyQt5-sip==12.13.0
PyQtWebEngine==5.15.6
PyRect==0.2.0
PyScreeze==1.0.1
PySocks==1.7.1
PyWave==0.5.0
PyWavelets==1.7.0
PyYAML==6.0.1
Pygments==2.15.1
QDarkStyle==3.2.3
QtAwesome==1.3.1
QtPy==2.4.1
RPi.GPIO==0.7.1
Rtree==1.0.1
SQLAlchemy==2.0.34
Scrapy==2.11.1
SecretStorage==3.3.1
Send2Trash==1.8.2
SpeechRecognition==3.14.4
Sphinx==7.3.7
Twisted==23.10.0
Unidecode==1.3.8
WMI==1.4.9
Werkzeug==3.0.3
absl-py==2.4.0
affine==2.4.0
aiobotocore==2.12.3
aiofiles==24.1.0
aiohappyeyeballs==2.4.0
aiohttp==3.10.5
aioitertools==0.7.1
aiosignal==1.2.0
alabaster==0.7.16
altair==5.0.1
ambivalent==0.3.0
annotated-doc==0.0.4
annotated-types==0.7.0
anyio==4.2.0
anytree==2.13.0
appdirs==1.4.4
arabic-reshaper==3.0.1
arcade==3.3.3
argon2-cffi==21.3.0
argon2-cffi-bindings==21.2.0
arrow==1.2.3
arviz==0.22.0
asgiref==3.11.1
asn1crypto==1.5.1
astroid==2.14.2
astropy==6.1.3
astropy-iers-data==0.2024.9.2.0.33.23
asttokens==2.0.5
astunparse==1.6.3
async-lru==2.0.4
asyncpg==0.31.0
asyncssh==2.21.1
atomicwrites==1.4.0
attrs==26.1.0
audioread==3.1.0
autocommand==2.2.2
autopep8==2.0.4
backports.tarfile==1.2.0
basemap==1.4.0
basemap-data==1.3.2
bcrypt==3.2.0
beautifulsoup4==4.12.3
binaryornot==0.4.4
biopython==1.86
black==24.8.0
bleach==4.1.0
blinker==1.6.2
blis==1.3.3
board==1.0
bokeh==3.6.0
boto3==1.37.4
botocore==1.37.38
branca==0.8.2
brotli==1.2.0
cachetools==5.3.3
cairocffi==1.7.1
camelot-py==1.0.9
catalogue==2.0.10
certifi==2026.5.20
cffi==2.0.0
cfgv==3.5.0
cftime==1.6.5
chardet==5.2.0
charset-normalizer==3.3.2
choreographer==1.3.0
click==8.1.7
click-plugins==1.1.1.2
cligj==0.7.2
cloudpathlib==0.24.0
cloudpickle==3.0.0
clr==1.0.3
cmudict==1.1.3
colorama==0.4.6
colorcet==3.1.0
colormaps==0.5.0
comm==0.2.1
confection==0.1.5
cons==0.4.7
constantly==23.10.4
contourpy==1.2.0
cookiecutter==2.6.0
countryinfo==0.1.2
crypto==1.4.1
cryptography==46.0.7
cssselect==1.2.0
cssselect2==0.8.0
curl_cffi==0.15.0
cycler==0.11.0
cymem==2.0.13
cytoolz==0.12.2
dask==2024.8.2
dask-expr==1.1.13
databricks-sql-connector==4.2.2
datashader==0.16.3
dearpygui==2.1.1
debugpy==1.6.7
decorator==5.1.1
defusedxml==0.7.1
deprecation==2.1.0
diagrams==0.25.1
diff-match-patch==20200713
dill==0.3.8
discord==2.3.2
discord.py==2.7.1
distlib==0.4.1
distributed==2024.8.2
distro==1.9.0
dlib==20.0.0
dnspython==2.8.0
docker==7.1.0
docstring-to-markdown==0.11
docutils==0.18.1
docx==0.2.4
docx2txt==0.9
einops==0.8.1
enchant==0.0.1
et-xmlfile==1.1.0
etuples==0.3.10
exchange_calendars==4.11.3
executing==0.8.3
fastapi==0.124.4
fastjsonschema==2.16.2
ffmpeg-python==0.2.0
ffmpy==1.0.0
filelock==3.29.1
filetype==1.2.0
fiona==1.10.1
flake8==7.0.0
flatbuffers==25.12.19
flet==0.28.3
folium==0.20.0
fonttools==4.51.0
fpdf==1.7.2
fqdn==1.5.1
freetype-py==2.5.1
frozendict==2.4.7
frozenlist==1.4.0
fsspec==2024.6.1
future==1.0.0
gTTS==2.5.4
gast==0.7.0
gensim==4.3.3
geographiclib==2.1
geopandas==1.1.1
geopy==2.4.1
gitdb==4.0.7
google==3.0.0
google-auth==2.53.0
google-auth-oauthlib==1.4.0
google-pasta==0.2.0
googletrans==4.0.2
gradio==6.1.0
gradio_client==2.0.1
graphviz==0.20.3
greenlet==3.5.1
groovy==0.1.2
grpcio==1.81.0
gspread==6.2.1
h11==0.14.0
h2==4.3.0
h5netcdf==1.8.1
h5py==3.11.0
hf-xet==1.5.0
holoviews==1.19.1
hpack==4.1.0
html5lib==1.1
httpcore==1.0.2
httpx==0.28.1
huggingface_hub==1.16.1
hvplot==0.11.0
hyperframe==6.1.0
hyperlink==21.0.0
icalendar==6.3.2
identify==2.6.19
idna==3.7
imagecodecs==2023.1.23
imageio==2.33.1
imageio-ffmpeg==0.6.0
imagesize==1.4.1
imbalanced-learn==0.12.3
imgkit==1.2.3
importlib-metadata==7.0.1
importlib_metadata==8.0.0
importlib_resources==6.4.0
incremental==22.10.0
inflect==7.3.1
inflection==0.5.1
iniconfig==1.1.1
intake==2.0.7
intervaltree==3.1.0
ipykernel==6.28.0
ipython==8.27.0
ipython-genutils==0.2.0
ipywidgets==7.8.1
iso8601==2.1.0
isoduration==20.11.0
isort==5.13.2
itemadapter==0.3.0
itemloaders==1.1.0
itsdangerous==2.2.0
jaraco.classes==3.2.1
jaraco.collections==5.1.0
jaraco.context==5.3.0
jaraco.functools==4.0.1
jaraco.text==3.12.1
jax==0.4.34
jaxlib==0.4.34
jedi==0.19.1
jeepney==0.7.1
jellyfish==1.0.1
jieba==0.42.1
jiter==0.15.0
jmespath==1.0.1
joblib==1.4.2
json5==0.9.6
jsonlines==4.0.0
jsonpickle==4.1.2
jsonpointer==3.1.1
jsonschema==4.23.0
jsonschema-specifications==2023.7.1
jupyter==1.0.0
jupyter-console==6.6.3
jupyter-events==0.10.0
jupyter-lsp==2.2.0
jupyter_client==8.6.0
jupyter_core==5.7.2
jupyter_server==2.14.1
jupyter_server_terminals==0.4.4
jupyterlab==4.2.5
jupyterlab-pygments==0.1.2
jupyterlab-widgets==1.0.0
jupyterlab_server==2.27.3
kaleido==1.2.0
keras==3.12.0
keyboard==0.13.5
keyring==24.3.1
kiwisolver==1.4.4
korean-lunar-calendar==0.3.1
language_tool_python==3.1.0
lazy-object-proxy==1.10.0
lazy_loader==0.4
lckr_jupyterlab_variableinspector==3.1.0
libclang==18.1.1
librosa==0.11.0
lightgbm==4.6.0
linkify-it-py==2.0.0
llvmlite==0.43.0
lmdb==1.4.1
locket==1.0.0
logical-unification==0.4.7
logistro==2.0.1
loguru==0.7.3
lxml==6.1.1
lz4==4.4.5
magika==0.6.3
markdown-it-py==2.2.0
markdown2==2.5.4
markdownify==1.2.2
markitdown==0.1.4
matlab==0.1
matplotlib==3.8.4
matplotlib-inline==0.1.6
matplotlib-venn==1.1.2
matplotx==0.3.10
mccabe==0.7.0
mcpi==1.2.1
mdit-py-plugins==0.3.0
mdurl==0.1.0
mendeleev==0.19.0
miniKanren==1.0.5
mistune==2.0.4
mizani==0.14.4
ml-dtypes==0.3.2
mne==1.11.0
more-itertools==10.3.0
moviepy==2.2.1
mpmath==1.3.0
msgpack==1.0.3
mtcnn==1.0.0
multidict==6.0.4
multipledispatch==0.6.0
multitasking==0.0.13
murmurhash==1.0.15
music21==9.9.1
mutagen==1.47.0
mypy==1.11.2
mypy-extensions==1.0.0
namex==0.1.0
narwhals==2.22.1
nashpy==0.0.43
nbclassic==1.3.3
nbclient==0.8.0
nbconvert==7.16.4
nbformat==5.10.4
nest-asyncio==1.6.0
netCDF4==1.7.3
networkx==3.3
nltk==3.9.1
nodeenv==1.10.0
notebook==7.2.2
notebook_shim==0.2.3
numba==0.60.0
numexpr==2.8.7
numpy==1.26.4
numpy-financial==1.0.0
numpydoc==1.7.0
nvidia-nccl-cu12==2.30.4
oauthlib==3.3.1
onnxruntime==1.26.0
openai==2.11.0
opencv-python==4.11.0.86
opencv-python-headless==4.11.0.86
openpyxl==3.1.5
opt_einsum==3.4.0
optree==0.19.1
orjson==3.11.9
oscrypto==1.3.0
outcome==1.3.0.post0
overrides==7.4.0
packaging==23.2
pandas==2.2.2
pandas-datareader==0.10.0
pandocfilters==1.5.0
panel==1.5.2
param==2.1.1
parsel==1.8.1
parso==0.8.3
partd==1.4.1
pathspec==0.10.3
patsy==0.5.6
pdf2image==1.17.0
pdfkit==1.0.0
pdfminer.six==20251107
pdfplumber==0.11.8
pdfrw==0.4
peewee==4.0.6
pexpect==4.8.0
pg8000==1.31.5
pickleshare==0.7.5
pillow==11.3.0
pip==26.1.2
pip-licenses==5.5.0
platformdirs==4.10.0
playwright==1.57.0
plotly==6.5.0
plotnine==0.15.2
pluggy==1.0.0
ply==3.11
polars==1.36.1
polars-runtime-32==1.36.1
pooch==1.9.0
pre_commit==4.6.0
preshed==3.0.13
prettytable==3.17.0
priority==2.0.0
proglog==0.1.12
prometheus-client==0.14.1
prompt-toolkit==3.0.43
pronouncing==0.2.0
protobuf==4.25.3
psutil==5.9.0
ptyprocess==0.7.0
pure-eval==0.2.2
py-cpuinfo==9.0.0
py4j==0.10.9.9
pyHanko==0.34.1
pyOpenSSL==25.3.0
pyTelegramBotAPI==4.34.0
pyarrow==16.1.0
pyasn1==0.4.8
pyasn1-modules==0.2.8
pybreaker==1.4.1
pycairo==1.29.0
pycodestyle==2.11.1
pycountry==24.6.1
pycparser==2.21
pycryptodomex==3.23.0
pyct==0.5.0
pycurl==7.45.3
pydantic==2.12.4
pydantic_core==2.41.5
pydeck==0.8.0
pydocstyle==6.3.0
pydot==4.0.1
pydub==0.25.1
pydyf==0.12.1
pyee==13.0.1
pyerfa==2.0.1.4
pyfiglet==0.8.post1
pyflakes==3.2.0
pyglet==2.1.11
pygraphviz==1.14
pyhanko-certvalidator==0.30.2
pylint==2.16.2
pylint-venv==3.0.3
pylog==1.1
pyls-spyder==0.4.0
pyluach==2.3.0
pymc==5.25.1
pymongo==4.15.5
pymunk==6.9.0
pyodbc==5.1.0
pyogrio==0.12.1
pyoo==1.4
pypandoc==1.16.2
pyparsing==3.1.2
pypdf==5.9.0
pypdfium2==5.2.0
pyperclip==1.11.0
pyphen==0.17.2
pyppeteer==0.0.25
pyproj==3.6.1
pyprover==0.6.2
pyshp==2.3.1
pyspark==4.0.1
pytensor==2.31.7
pytesseract==0.3.13
pytest==7.4.4
pytest-timeout==2.4.0
pyth3==0.7
python-bidi==0.6.10
python-dateutil==2.9.0.post0
python-discovery==1.4.0
python-docx==1.2.0
python-dotenv==1.2.2
python-json-logger==2.0.7
python-lsp-black==2.0.0
python-lsp-jsonrpc==1.1.2
python-lsp-server==1.10.0
python-multipart==0.0.32
python-pptx==1.0.2
python-slugify==5.0.2
python3-xlib==0.15
pytiled_parser==2.2.9
pytoolconfig==1.2.6
pyttsx3==2.99
pytweening==1.2.0
pytz==2024.1
pyviz_comms==3.0.2
pyxdg==0.27
pyxlsb==1.0.10
pyzbar==0.1.9
pyzmq==25.1.2
qrcode==8.2
qstylizer==0.2.2
qtconsole==5.5.1
queuelib==1.6.2
rarfile==4.2
rasterio==1.4.4
rdflib==7.5.0
rdkit==2025.9.3
referencing==0.30.2
regex==2024.9.11
repath==0.9.0
reportlab==4.4.6
requests==2.34.2
requests-file==1.5.1
requests-oauthlib==2.0.0
rfc3339-validator==0.1.4
rfc3986-validator==0.1.1
rich==15.0.0
rlPyCairo==0.4.0
rope==1.12.0
rpds-py==0.10.6
s3fs==2024.6.1
s3transfer==0.11.5
safehttpx==0.1.7
scikit-image==0.24.0
scikit-learn==1.5.1
scipy==1.13.1
scramp==1.4.8
seaborn==0.13.2
selenium==4.39.0
semantic-version==2.10.0
serial==0.0.97
service-identity==18.1.0
setuptools==75.1.0
shap==0.49.1
shapely==2.1.2
shellescape==3.8.1
shellingham==1.5.4
simplejson==4.1.1
sip==6.7.12
six==1.16.0
slicer==0.0.8
smart-open==5.2.1
smmap==4.0.0
sniffio==1.3.0
snowballstemmer==2.2.0
snowflake-connector-python==4.1.1
sortedcontainers==2.4.0
soundfile==0.13.1
soupsieve==2.5
soxr==1.1.0
spacy==3.8.11
spacy-legacy==3.0.12
spacy-loggers==1.0.5
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.10
spyder==5.5.1
spyder-kernels==2.5.0
sqlparse==0.5.5
srsly==2.5.3
stack-data==0.2.0
starlette==0.50.0
statsmodels==0.14.6
streamlit==1.52.1
svglib==1.6.0
svgwrite==1.4.3
sympy==1.14.0
tables==3.10.1
tabula==1.0.5
tabulate==0.9.0
tblib==1.7.0
telebot==0.0.5
telegram==0.0.1
tenacity==8.2.3
tensorboard==2.16.2
tensorboard-data-server==0.7.2
tensorflow==2.16.1
termcolor==3.3.0
terminado==0.17.1
text-unidecode==1.3
textblob==0.19.0
textdistance==4.2.1
textstat==0.7.12
thinc==8.3.11
threadpoolctl==3.5.0
three-merge==0.1.1
thrift==0.20.0
tifffile==2023.4.12
tika==3.1.0
tiktoken==0.12.0
tinycss2==1.5.1
tinyhtml5==2.1.0
tldextract==5.1.2
toml==0.10.2
tomli==2.0.1
tomlkit==0.13.3
toolz==1.1.0
torch==2.9.1+cpu
torchaudio==2.9.1+cpu
torchtext==0.18.0+cpu
torchvision==0.24.1+cpu
tornado==6.4.1
tqdm==4.66.5
traitlets==5.14.3
trimesh==4.10.1
trio==0.33.0
trio-websocket==0.12.2
typeguard==4.3.0
typer==0.26.7
typer-slim==0.24.0
typing-inspection==0.4.2
typing_extensions==4.12.2
tzdata==2026.2
tzlocal==5.3.1
uc-micro-py==1.0.1
ujson==5.10.0
unicodedata2==15.1.0
uri-template==1.3.0
uritools==6.1.2
urllib3==2.7.0
uvicorn==0.49.0
virtualenv==21.4.2
vsdx==0.5.19
w3lib==1.21.0
wasabi==1.1.3
watchdog==4.0.1
wavfile==4.7.2
wcwidth==0.2.5
weasel==0.4.3
weasyprint==66.0
webcolors==25.10.0
webencodings==0.5.1
websocket-client==1.8.0
websockets==16.0
whatthepatch==1.0.2
wheel==0.43.0
widgetsnbextension==3.6.6
word2number==1.1
wordcloud==1.9.4
wrapt==1.14.1
wsproto==1.2.0
wurlitzer==3.0.2
xarray==2025.6.1
xarray-einstats==0.9.1
xgboost==3.1.2
xhtml2pdf==0.2.17
xlrd==2.0.2
xlsxwriter==3.2.9
xml-python==0.4.3
xyzservices==2022.9.0
yapf==0.40.2
yarl==1.11.0
yfinance==0.2.66
yt-dlp==2024.10.22
zict==3.0.0
zipp==3.17.0
zope.interface==5.4.0
zopfli==0.4.2

The code has no network or file access: it reads data only through the step's Inputs, and what it returns is all that leaves the sandbox.

Limits

Limit Value
Code 20,000 characters
Inputs 20 per step, 1 MB of JSON together
Returned dict 256 KB of JSON
Timeout 1–120 seconds, 30 by default
Placement Not on a parallel branch: join the branches before the code step

Code runs

Every time a code step runs, it uses one code run:

  • a flow run uses one per code step it reaches;
  • inside a loop, the step uses one run per item, so a loop over 50 rows uses 50;
  • a test in the builder (Run from here) uses one, marked as a test.

A run is used once the code has started, so it counts when the code raises an error, times out or returns something that is not a JSON dict. It is not used when the step stops before the code starts: no runs left, the sandbox was busy or unavailable, an input was missing or too large, or code steps are not enabled.

The run detail says so on the step: Used 1 code run, Used 1 code run (test) or No code run used, and a failed step names its cause in plain language.

Where the runs come from

Code runs come with your licence as a monthly allowance (it starts again on the 1st of each month, UTC; unused runs do not carry over), as top-ups (a fixed number of runs, used after the allowance), or both. The allowance is used first, then the oldest top-up. Your vendor adds runs; they arrive with the licence check-in every six hours.

When no runs are left, the code step fails without running and the run stops there. Once the allowance resets or a top-up arrives, Retry from failure on the run picks it up from that step. The builder shows the runs left next to the step, so you see it coming. Anyone with the licensing.runs.read role also gets a notice in the bell and under Tasks → Updates when fewer than 20% and fewer than 5% of the month's runs are left, and when they are used up. It is in their own language and opens the Code runs page.

The Code runs page

Administration → Platform → Code runs shows, for anyone with the licensing.runs.read role:

  • how many runs are left, split into allowance and top-ups;
  • the runs used this month, flow runs and tests apart;
  • when the allowance resets, and roughly when the runs will run out at the recent pace;
  • this month's and last month's estimated sandbox cost, in your licence's currency, with the five flows driving it;
  • every grant received, including ended ones, each with its id to copy;
  • the runs per day or month, and which flows used them;
  • the Run ledger of one flow run.

Estimated sandbox cost

The cost card shows what the cloud sandbox costs, always as an estimate at list price, never an invoice. Azure bills each sandbox session per started hour, from the moment it is allocated: a session of 59 or 60 minutes is 1 hour, one of 61 minutes is 2, and a session that is still open counts up to now. A session counts whole in the UTC month it started in, so a session that spans midnight on the 1st is not split and a month can differ slightly from Azure's own bill. Only the five flows with the most hours are listed, so they can add up to less than the month total.

On an unlimited allowance this is what your organisation's own Azure bill grows by, so it leads the page; on every other plan it sits under the runs-left figures. The price per hour defaults to the EUR list price for North Europe; ask your vendor if you have a negotiated rate. AI agents can read the same figures through get_code_run_meter.

Check for new runs asks the licence service right away instead of waiting for the next check-in, at most once a minute.

Tracing one run to its grant

For anyone with the licensing.runs.read role, the badge on a code step in the run detail (Used 1 code run, Used 1 code run (test) or No code run used) is a link. It opens the Run ledger tab on the Code runs page for that step. Show every step widens it to the whole flow run. Each row shows:

  • what happened to the run: Charged, Given back with why under it (the code never started, or nobody settled it within 30 minutes) or Not settled yet, and Test for a test in the builder;
  • when it was reserved and settled;
  • the allowance month it counted in (a top-up has no month);
  • the grant it came from, with its id to copy. The Grants tab and your vendor's licence portal show the same id.

A step that was given back and ran again shows its latest attempt. A row without a grant has not taken a run yet. The tab's address holds the run and the step, so you can share the link.

The AI assistant can answer the same question. Give it the run's id and ask which grant paid for the run; it needs the same licensing.runs.read role.

When code steps are not enabled

Some environments run without the code sandbox. There the Code step shows in the palette, disabled, with the reason, and an existing code step's panel and the Code runs page say that code steps aren't enabled. A flow that already holds a code step (from a template, or copied from another environment) cannot be submitted or activated, and the refusal names the step: Code steps aren't enabled for this environment, so "Score rows" can't run. Contact Datahub to enable them, or remove the step. A zero run balance does not block activation: runs can be added afterwards.

Troubleshooting

Every failed code step says whether it used a run. The run detail shows the cause in your language and names what it knows: the input that had no value and the key it reads, the settings to correct, the time limit in seconds. For an error in the code itself it also shows the code's error and the last lines the code wrote to stderr. The run's execution log reads in your language too.

The step says Run used? What to do
There were no code runs left No Wait for the reset date it names, or ask an administrator to get more runs from your vendor; then Retry from failure.
The code service was busy No Retry the run from this step in a moment.
The code service couldn't be reached No Retry later; tell an administrator if it keeps happening.
This step's input "amount" reads "total", which had no value No Make an earlier step on this path write that key, or point the input at one that exists.
This step's inputs were too large to send No Filter or summarise the data in an earlier step, or use fewer inputs.
This code step isn't set up completely No Open the step and correct the settings it names (code, inputs, output key or timeout).
The Python code ran and raised an error Yes Fix the code using the error shown, and test with Run from here.
The Python code doesn't define main(inputs) Yes Add a function main(inputs) that returns a dict.
The Python code ran past its limit of 30 seconds Yes Make it faster, pass less data in, or raise the timeout (up to 120 s).
The Python code returned something the flow can't store Yes Return a dict of JSON values: convert DataFrames, dates, sets and NumPy numbers first, and drop keys starting with _.
The Python code returned keys the flow keeps for itself Yes Rename the keys it names in the dict main(inputs) returns.
The Python code returned text with a NUL character Yes Remove that character from the values it returns.
The Python code returned more than the 256 KB a step may store Yes Return a summary or fewer rows.

See also

  • Flows


    Building, testing, approving and running flows.

  • Flow Capabilities


    Governed platform operations inside a flow: metrics, warehouse queries, notifications.