# Built-in python requirements plugin skips layer-only services (no functions defined)

**URL:** <https://forum.serverless.com/t/built-in-python-requirements-plugin-skips-layer-only-services-no-functions-defined/21688>\
**Category:** Serverless Framework\
**Tags:** lambda\
**Created:** [March 17, 2026, 3:53am UTC](https://forum.serverless.com/t/built-in-python-requirements-plugin-skips-layer-only-services-no-functions-defined/21688 "2026-03-17T03:53:49Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![coolloic](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.serverless.com/coolloic/32/7052_2.png) [@coolloic](https://forum.serverless.com/u/coolloic)\
**Post date:** [March 17, 2026, 3:53am UTC](https://forum.serverless.com/t/built-in-python-requirements-plugin-skips-layer-only-services-no-functions-defined/21688/1 "2026-03-17T03:53:49Z")

</div>

The built-in serverless-python-requirements plugin in Serverless Framework v4 does not generate the PythonRequirementsLambdaLayer resource or PythonRequirementsLambdaLayerQualifiedArn  
output for layer-only services (services with custom.pythonRequirements.layer configured but no functions: block).

**Root Cause**

The isFunctionRuntimePython guard in the built-in plugin was rewritten from the standalone version. When no functionObj is present in the hook arguments, the built-in version falls  
through to a service-level check that iterates this.serverless.service.functions. For a layer-only service, this is empty, so it returns false — causing before and after hooks (including  
layerRequirements()) to be skipped entirely.

**Built-in (v4)** — [serverless/packages/serverless/lib/plugins/python/index.js at 83677fd76661a14d0447c5c38f2628e6598f1546 · serverless/serverless · GitHub](https://github.com/serverless/serverless/blob/83677fd76661a14d0447c5c38f2628e6598f1546/packages/serverless/lib/plugins/python/index.js#L242-L258:)

```auto
const isFunctionRuntimePython = (args) => {
const providerRuntime = this.serverless.service.provider.runtime
if (args[1]?.functionObj) {
const functionRuntime = args[1].functionObj.runtime
const runtime = functionRuntime || providerRuntime
return runtime ? runtime.startsWith(‘python’) : false
}
// Service-level hook: check if ANY function uses Python
const allFunctions = this.serverless.service.functions || {}
const hasPythonFunction = Object.values(allFunctions).some((func) => {
const runtime = func.runtime || providerRuntime
return runtime && runtime.startsWith(‘python’)
})
const hasPythonAgent = this.targetAgents.length > 0
return hasPythonFunction || hasPythonAgent
}

```

**Standalone (pre-v4)** — [serverless-python-requirements/index.js at master · serverless/serverless-python-requirements · GitHub](https://github.com/serverless/serverless-python-requirements/blob/master/index.js#L199-L204:)

```auto
const isFunctionRuntimePython = (args) => {
if (!args[1].functionObj || !args[1].functionObj.runtime) {
   return true;
}
   return args[1].functionObj.runtime.startsWith(‘python’);
};

```

```auto
The standalone version returned true when functionObj was absent, so layer-only services worked. The built-in version returns false.

```

**Steps to Reproduce**

1. Create a service with custom.pythonRequirements.layer configured and no functions: block
2. Deploy with Serverless Framework v4
3. The PythonRequirementsLambdaLayer resource and PythonRequirementsLambdaLayerQualifiedArn output are not generated

**Expected Behaviour**

When custom.pythonRequirements.layer is configured, the plugin should process requirements and generate the layer resource/output regardless of whether functions are defined — matching  
the standalone plugin’s behaviour.
