{"record":{"id":"db8f55b6ab0ee537","repo":"keras-team/keras","slug":"cannot-add-call-context-args-after-the-layer-has-b","errorCode":null,"errorMessage":"Cannot add call-context args after the layer has been called.","messagePattern":"Cannot add call-context args after the layer has been called\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"keras/src/layers/layer.py","lineNumber":1881,"sourceCode":"            def call(self, x):\n                # We don't explicitly pass foo_mode here—Base Layer.__call__\n                # should inject it into `self.inner`\n                return self.inner(x)\n\n        sample_input = np.array([[1.0], [2.0]])\n\n        # Sequential model\n        seq = models.Sequential([Outer()])\n\n        # Tell the Sequential model to propagate foo_mode down\n        # the call-stack\n        seq._register_call_context_args(\"foo_mode\")\n\n        # foo_mode=True -> input + 1\n        out_true = seq(sample_input, foo_mode=True)\n        \"\"\"\n        if self._called:\n            raise RuntimeError(\n                \"Cannot add call-context args after the layer has been called.\"\n            )\n        self._call_context_args = self._call_context_args | set(names)\n\n        self._call_has_context_arg.update(\n            {arg: (arg in self.call_signature_parameters) for arg in names}\n        )\n\n\ndef is_backend_tensor_or_symbolic(x, allow_none=False):\n    if allow_none and x is None:\n        return True\n    return backend.is_tensor(x) or isinstance(x, backend.KerasTensor)\n\n\nclass CallSpec:\n    def __init__(self, signature, call_context_args, args, kwargs):\n        # Strip out user-supplied call-context args that this layer’s `call()`","sourceCodeStart":1863,"sourceCodeEnd":1899,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/layer.py#L1863-L1899","documentation":"Raised by Layer._register_call_context_args when you try to declare new call-context argument names after the layer has already been executed at least once. Keras records call-context args (custom keyword arguments passed through __call__) at build/spec time, and once self._called is True the call signature is frozen, so late registration is rejected to keep compute_output_spec and call dispatch consistent.","triggerScenarios":"Calling layer._register_call_context_args('foo_mode') (directly or via a wrapper like a Functional/Sequential model that registers context args on its sublayers) after the layer or an enclosing model has already been invoked, e.g. seq(sample_input) followed by seq._register_call_context_args(...).","commonSituations":"Building a wrapper layer that lazily registers context args inside call() instead of __init__; mutating a shared/serialized model after inference; reusing a loaded model and then adding new context kwargs.","solutions":["Move the _register_call_context_args(...) call into __init__ (or before the first __call__) so registration precedes any execution","If wrapping sublayers, register context args on each sublayer at construction time, not inside the wrapper's call()","If the model was already called, create a fresh instance (or re-instantiate the layer) and register the args before invoking it"],"exampleFix":"# before\nseq(sample_input)\nseq._register_call_context_args('foo_mode')  # RuntimeError\n\n# after\nclass MyLayer(keras.layers.Layer):\n    def __init__(self, **kwargs):\n        super().__init__(**kwargs)\n        self._register_call_context_args('foo_mode')\n    def call(self, inputs, foo_mode=False):\n        ...\nout = seq(sample_input, foo_mode=True)","handlingStrategy":"validation","validationCode":"if layer._called:\n    raise RuntimeError('register context args before calling the layer')","typeGuard":"def can_register(layer) -> bool:\n    return not getattr(layer, '_called', False)","tryCatchPattern":null,"preventionTips":["Register call-context args in __init__, never in call() or after inference","Treat the first __call__ as freezing the layer's call signature","Re-instantiate layers instead of mutating called ones"],"tags":["keras","layer","lifecycle","api-misuse"],"backgroundTag":"invalid-state-transition","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}