From c4a3c3465c74997792aba03260be35a3023f3911 Mon Sep 17 00:00:00 2001 From: henry3260 Date: Wed, 23 Sep 2026 20:12:38 +0800 Subject: [PATCH] Document that Go SDK registration closes at Serve Both rules were enforced in code without being written down anywhere a bundle author reads, so the first sign of either was a panic: one at startup, one on the task's first run under the supervisor. --- .../authoring-and-scheduling/language-sdks/go.rst | 11 ++++++++--- go-sdk/README.md | 6 +++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/airflow-core/docs/authoring-and-scheduling/language-sdks/go.rst b/airflow-core/docs/authoring-and-scheduling/language-sdks/go.rst index f84803843dcd6..72ea37bf66583 100644 --- a/airflow-core/docs/authoring-and-scheduling/language-sdks/go.rst +++ b/airflow-core/docs/authoring-and-scheduling/language-sdks/go.rst @@ -163,9 +163,14 @@ Dag, and the ``task_id`` must match a ``@task.stub`` function in that Dag. Neith function name, so a handler can be named whatever reads best in Go. ``TaskHandler`` also checks the signature of the function it is given and panics if the check fails -- for -instance when the function does not take an ``airflow.Context`` first, or does not return an ``error``. -Because ``main`` registers every handler before ``Serve``, a mistake stops the executable as soon as it -starts rather than when the task first runs. +instance when the function does not take an ``airflow.Context`` first, does not return an ``error``, or +declares a variadic ``...`` parameter, which no stub argument can fill. Because ``main`` registers every +handler before ``Serve``, a mistake stops the executable as soon as it starts rather than when the task +first runs. + +``Serve`` closes registration: a ``Register`` left below it in ``main`` panics rather than adding a handler +to the map the runtime is already answering from, so what a bundle can run never depends on how far +``main`` has got. A package that defines task handlers of its own can export them as a ``[]airflow.Registerable`` for ``main`` to pass on with ``bundle.Register(reports.Handlers()...)``. diff --git a/go-sdk/README.md b/go-sdk/README.md index 8b2e7f490f01f..14bed678abcc6 100644 --- a/go-sdk/README.md +++ b/go-sdk/README.md @@ -94,7 +94,11 @@ func main() { `TaskHandler` names the `dag_id` and the `task_id` explicitly; neither is derived from the Go function name, so a handler can be called whatever reads best in Go. It checks the signature of the function and -panics if the check fails, which stops the executable as it starts rather than when the task first runs. +panics if the check fails -- a variadic `...` parameter, which no stub argument can fill, is one such +failure -- so the executable stops as it starts rather than when the task first runs. `Serve` then closes +registration, so a `Register` left below it in `main` panics instead of changing what the running bundle +answers for. + A package that defines handlers of its own can export them as a `[]airflow.Registerable` for `main` to pass on with `bundle.Register(reports.Handlers()...)`.