We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`ak.fill_none(axis=None)` does nothing
### Version of Awkward Array

main

### Description and code to reproduce

The `apply` function for this case does not return (or recurse)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/awkward/operations/ak_fill_none.py`
Content:
```
1 # BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE
2 
3 import numbers
4 
5 import awkward as ak
6 
7 np = ak.nplikes.NumpyMetadata.instance()
8 
9 
10 def fill_none(array, value, axis=-1, highlevel=True, behavior=None):
11     """
12     Args:
13         array: Data in which to replace None with a given value.
14         value: Data with which to replace None.
15         axis (None or int): If None, replace all None values in the array
16             with the given value; if an int, The dimension at which this
17             operation is applied. The outermost dimension is `0`, followed
18             by `1`, etc., and negative values count backward from the
19             innermost: `-1` is the innermost  dimension, `-2` is the next
20             level up, etc.
21         highlevel (bool): If True, return an #ak.Array; otherwise, return
22             a low-level #ak.contents.Content subclass.
23         behavior (None or dict): Custom #ak.behavior for the output array, if
24             high-level.
25 
26     Replaces missing values (None) with a given `value`.
27 
28     For example, in the following `array`,
29 
30         ak.Array([[1.1, None, 2.2], [], [None, 3.3, 4.4]])
31 
32     The None values could be replaced with `0` by
33 
34         >>> ak.fill_none(array, 0)
35         <Array [[1.1, 0, 2.2], [], [0, 3.3, 4.4]] type='3 * var * float64'>
36 
37     The replacement value doesn't strictly need the same type as the
38     surrounding data. For example, the None values could also be replaced
39     by a string.
40 
41         >>> ak.fill_none(array, "hi")
42         <Array [[1.1, 'hi', 2.2], ... ['hi', 3.3, 4.4]] type='3 * var * union[float64, s...'>
43 
44     The list content now has a union type:
45 
46         >>> ak.type(ak.fill_none(array, "hi"))
47         3 * var * union[float64, string]
48 
49     The values could be floating-point numbers or strings.
50     """
51     with ak._errors.OperationErrorContext(
52         "ak.fill_none",
53         dict(
54             array=array, value=value, axis=axis, highlevel=highlevel, behavior=behavior
55         ),
56     ):
57         return _impl(array, value, axis, highlevel, behavior)
58 
59 
60 def _impl(array, value, axis, highlevel, behavior):
61     arraylayout = ak.operations.to_layout(array, allow_record=True, allow_other=False)
62     nplike = ak.nplikes.nplike_of(arraylayout)
63 
64     # Convert value type to appropriate layout
65     if (
66         isinstance(value, np.ndarray)
67         and issubclass(value.dtype.type, (np.bool_, np.number))
68         and len(value.shape) != 0
69     ):
70         valuelayout = ak.operations.to_layout(
71             nplike.asarray(value)[np.newaxis], allow_record=False, allow_other=False
72         )
73     elif isinstance(value, (bool, numbers.Number, np.bool_, np.number)) or (
74         isinstance(value, np.ndarray)
75         and issubclass(value.dtype.type, (np.bool_, np.number))
76     ):
77         valuelayout = ak.operations.to_layout(
78             nplike.asarray(value), allow_record=False, allow_other=False
79         )
80     elif (
81         ak._util.is_sized_iterable(value)
82         and not (isinstance(value, (str, bytes)))
83         or isinstance(value, (ak.highlevel.Record, ak.record.Record))
84     ):
85         valuelayout = ak.operations.to_layout(
86             value, allow_record=True, allow_other=False
87         )
88         if isinstance(valuelayout, ak.record.Record):
89             valuelayout = valuelayout.array[valuelayout.at : valuelayout.at + 1]
90         elif len(valuelayout) == 0:
91             offsets = ak.index.Index64(
92                 nplike.array([0, 0], dtype=np.int64), nplike=nplike
93             )
94             valuelayout = ak.contents.ListOffsetArray(offsets, valuelayout)
95         else:
96             valuelayout = ak.contents.RegularArray(valuelayout, len(valuelayout), 1)
97     else:
98         valuelayout = ak.operations.to_layout(
99             [value], allow_record=False, allow_other=False
100         )
101 
102     def maybe_fillna(layout):
103         if layout.is_OptionType:
104             return layout.fill_none(valuelayout)
105         else:
106             return layout
107 
108     if axis is None:
109 
110         def action(layout, depth, depth_context, **kwargs):
111             layout = maybe_fillna(layout)
112 
113     else:
114 
115         def action(layout, depth, depth_context, **kwargs):
116             posaxis = layout.axis_wrap_if_negative(depth_context["posaxis"])
117             depth_context["posaxis"] = posaxis
118             if posaxis + 1 < depth:
119                 return layout
120             elif posaxis + 1 == depth:
121                 return maybe_fillna(layout)
122 
123     depth_context = {"posaxis": axis}
124     out = arraylayout.recursively_apply(action, behavior, depth_context=depth_context)
125 
126     return ak._util.wrap(out, ak._util.behavior_of(array, behavior=behavior), highlevel)
127
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/awkward/operations/ak_fill_none.py b/src/awkward/operations/ak_fill_none.py
--- a/src/awkward/operations/ak_fill_none.py
+++ b/src/awkward/operations/ak_fill_none.py
@@ -107,8 +107,8 @@
 
     if axis is None:
 
-        def action(layout, depth, depth_context, **kwargs):
-            layout = maybe_fillna(layout)
+        def action(layout, continuation, **kwargs):
+            return maybe_fillna(continuation())
 
     else:

{"golden_diff": "diff --git a/src/awkward/operations/ak_fill_none.py b/src/awkward/operations/ak_fill_none.py\n--- a/src/awkward/operations/ak_fill_none.py\n+++ b/src/awkward/operations/ak_fill_none.py\n@@ -107,8 +107,8 @@\n \n     if axis is None:\n \n-        def action(layout, depth, depth_context, **kwargs):\n-            layout = maybe_fillna(layout)\n+        def action(layout, continuation, **kwargs):\n+            return maybe_fillna(continuation())\n \n     else:\n", "issue": "`ak.fill_none(axis=None)` does nothing\n### Version of Awkward Array\r\n\r\nmain\r\n\r\n### Description and code to reproduce\r\n\r\nThe `apply` function for this case does not return (or recurse)\n", "before_files": [{"content": "# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE\n\nimport numbers\n\nimport awkward as ak\n\nnp = ak.nplikes.NumpyMetadata.instance()\n\n\ndef fill_none(array, value, axis=-1, highlevel=True, behavior=None):\n    \"\"\"\n    Args:\n        array: Data in which to replace None with a given value.\n        value: Data with which to replace None.\n        axis (None or int): If None, replace all None values in the array\n            with the given value; if an int, The dimension at which this\n            operation is applied. The outermost dimension is `0`, followed\n            by `1`, etc., and negative values count backward from the\n            innermost: `-1` is the innermost  dimension, `-2` is the next\n            level up, etc.\n        highlevel (bool): If True, return an #ak.Array; otherwise, return\n            a low-level #ak.contents.Content subclass.\n        behavior (None or dict): Custom #ak.behavior for the output array, if\n            high-level.\n\n    Replaces missing values (None) with a given `value`.\n\n    For example, in the following `array`,\n\n        ak.Array([[1.1, None, 2.2], [], [None, 3.3, 4.4]])\n\n    The None values could be replaced with `0` by\n\n        >>> ak.fill_none(array, 0)\n        <Array [[1.1, 0, 2.2], [], [0, 3.3, 4.4]] type='3 * var * float64'>\n\n    The replacement value doesn't strictly need the same type as the\n    surrounding data. For example, the None values could also be replaced\n    by a string.\n\n        >>> ak.fill_none(array, \"hi\")\n        <Array [[1.1, 'hi', 2.2], ... ['hi', 3.3, 4.4]] type='3 * var * union[float64, s...'>\n\n    The list content now has a union type:\n\n        >>> ak.type(ak.fill_none(array, \"hi\"))\n        3 * var * union[float64, string]\n\n    The values could be floating-point numbers or strings.\n    \"\"\"\n    with ak._errors.OperationErrorContext(\n        \"ak.fill_none\",\n        dict(\n            array=array, value=value, axis=axis, highlevel=highlevel, behavior=behavior\n        ),\n    ):\n        return _impl(array, value, axis, highlevel, behavior)\n\n\ndef _impl(array, value, axis, highlevel, behavior):\n    arraylayout = ak.operations.to_layout(array, allow_record=True, allow_other=False)\n    nplike = ak.nplikes.nplike_of(arraylayout)\n\n    # Convert value type to appropriate layout\n    if (\n        isinstance(value, np.ndarray)\n        and issubclass(value.dtype.type, (np.bool_, np.number))\n        and len(value.shape) != 0\n    ):\n        valuelayout = ak.operations.to_layout(\n            nplike.asarray(value)[np.newaxis], allow_record=False, allow_other=False\n        )\n    elif isinstance(value, (bool, numbers.Number, np.bool_, np.number)) or (\n        isinstance(value, np.ndarray)\n        and issubclass(value.dtype.type, (np.bool_, np.number))\n    ):\n        valuelayout = ak.operations.to_layout(\n            nplike.asarray(value), allow_record=False, allow_other=False\n        )\n    elif (\n        ak._util.is_sized_iterable(value)\n        and not (isinstance(value, (str, bytes)))\n        or isinstance(value, (ak.highlevel.Record, ak.record.Record))\n    ):\n        valuelayout = ak.operations.to_layout(\n            value, allow_record=True, allow_other=False\n        )\n        if isinstance(valuelayout, ak.record.Record):\n            valuelayout = valuelayout.array[valuelayout.at : valuelayout.at + 1]\n        elif len(valuelayout) == 0:\n            offsets = ak.index.Index64(\n                nplike.array([0, 0], dtype=np.int64), nplike=nplike\n            )\n            valuelayout = ak.contents.ListOffsetArray(offsets, valuelayout)\n        else:\n            valuelayout = ak.contents.RegularArray(valuelayout, len(valuelayout), 1)\n    else:\n        valuelayout = ak.operations.to_layout(\n            [value], allow_record=False, allow_other=False\n        )\n\n    def maybe_fillna(layout):\n        if layout.is_OptionType:\n            return layout.fill_none(valuelayout)\n        else:\n            return layout\n\n    if axis is None:\n\n        def action(layout, depth, depth_context, **kwargs):\n            layout = maybe_fillna(layout)\n\n    else:\n\n        def action(layout, depth, depth_context, **kwargs):\n            posaxis = layout.axis_wrap_if_negative(depth_context[\"posaxis\"])\n            depth_context[\"posaxis\"] = posaxis\n            if posaxis + 1 < depth:\n                return layout\n            elif posaxis + 1 == depth:\n                return maybe_fillna(layout)\n\n    depth_context = {\"posaxis\": axis}\n    out = arraylayout.recursively_apply(action, behavior, depth_context=depth_context)\n\n    return ak._util.wrap(out, ak._util.behavior_of(array, behavior=behavior), highlevel)\n", "path": "src/awkward/operations/ak_fill_none.py"}], "after_files": [{"content": "# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE\n\nimport numbers\n\nimport awkward as ak\n\nnp = ak.nplikes.NumpyMetadata.instance()\n\n\ndef fill_none(array, value, axis=-1, highlevel=True, behavior=None):\n    \"\"\"\n    Args:\n        array: Data in which to replace None with a given value.\n        value: Data with which to replace None.\n        axis (None or int): If None, replace all None values in the array\n            with the given value; if an int, The dimension at which this\n            operation is applied. The outermost dimension is `0`, followed\n            by `1`, etc., and negative values count backward from the\n            innermost: `-1` is the innermost  dimension, `-2` is the next\n            level up, etc.\n        highlevel (bool): If True, return an #ak.Array; otherwise, return\n            a low-level #ak.contents.Content subclass.\n        behavior (None or dict): Custom #ak.behavior for the output array, if\n            high-level.\n\n    Replaces missing values (None) with a given `value`.\n\n    For example, in the following `array`,\n\n        ak.Array([[1.1, None, 2.2], [], [None, 3.3, 4.4]])\n\n    The None values could be replaced with `0` by\n\n        >>> ak.fill_none(array, 0)\n        <Array [[1.1, 0, 2.2], [], [0, 3.3, 4.4]] type='3 * var * float64'>\n\n    The replacement value doesn't strictly need the same type as the\n    surrounding data. For example, the None values could also be replaced\n    by a string.\n\n        >>> ak.fill_none(array, \"hi\")\n        <Array [[1.1, 'hi', 2.2], ... ['hi', 3.3, 4.4]] type='3 * var * union[float64, s...'>\n\n    The list content now has a union type:\n\n        >>> ak.type(ak.fill_none(array, \"hi\"))\n        3 * var * union[float64, string]\n\n    The values could be floating-point numbers or strings.\n    \"\"\"\n    with ak._errors.OperationErrorContext(\n        \"ak.fill_none\",\n        dict(\n            array=array, value=value, axis=axis, highlevel=highlevel, behavior=behavior\n        ),\n    ):\n        return _impl(array, value, axis, highlevel, behavior)\n\n\ndef _impl(array, value, axis, highlevel, behavior):\n    arraylayout = ak.operations.to_layout(array, allow_record=True, allow_other=False)\n    nplike = ak.nplikes.nplike_of(arraylayout)\n\n    # Convert value type to appropriate layout\n    if (\n        isinstance(value, np.ndarray)\n        and issubclass(value.dtype.type, (np.bool_, np.number))\n        and len(value.shape) != 0\n    ):\n        valuelayout = ak.operations.to_layout(\n            nplike.asarray(value)[np.newaxis], allow_record=False, allow_other=False\n        )\n    elif isinstance(value, (bool, numbers.Number, np.bool_, np.number)) or (\n        isinstance(value, np.ndarray)\n        and issubclass(value.dtype.type, (np.bool_, np.number))\n    ):\n        valuelayout = ak.operations.to_layout(\n            nplike.asarray(value), allow_record=False, allow_other=False\n        )\n    elif (\n        ak._util.is_sized_iterable(value)\n        and not (isinstance(value, (str, bytes)))\n        or isinstance(value, (ak.highlevel.Record, ak.record.Record))\n    ):\n        valuelayout = ak.operations.to_layout(\n            value, allow_record=True, allow_other=False\n        )\n        if isinstance(valuelayout, ak.record.Record):\n            valuelayout = valuelayout.array[valuelayout.at : valuelayout.at + 1]\n        elif len(valuelayout) == 0:\n            offsets = ak.index.Index64(\n                nplike.array([0, 0], dtype=np.int64), nplike=nplike\n            )\n            valuelayout = ak.contents.ListOffsetArray(offsets, valuelayout)\n        else:\n            valuelayout = ak.contents.RegularArray(valuelayout, len(valuelayout), 1)\n    else:\n        valuelayout = ak.operations.to_layout(\n            [value], allow_record=False, allow_other=False\n        )\n\n    def maybe_fillna(layout):\n        if layout.is_OptionType:\n            return layout.fill_none(valuelayout)\n        else:\n            return layout\n\n    if axis is None:\n\n        def action(layout, continuation, **kwargs):\n            return maybe_fillna(continuation())\n\n    else:\n\n        def action(layout, depth, depth_context, **kwargs):\n            posaxis = layout.axis_wrap_if_negative(depth_context[\"posaxis\"])\n            depth_context[\"posaxis\"] = posaxis\n            if posaxis + 1 < depth:\n                return layout\n            elif posaxis + 1 == depth:\n                return maybe_fillna(layout)\n\n    depth_context = {\"posaxis\": axis}\n    out = arraylayout.recursively_apply(action, behavior, depth_context=depth_context)\n\n    return ak._util.wrap(out, ak._util.behavior_of(array, behavior=behavior), highlevel)\n", "path": "src/awkward/operations/ak_fill_none.py"}]}