本地调试 sam local invoke 报错主因是函数入口路径错误、handler 模块未正确配置或缺失 __init__.py;api 返回 502/超时多因阻塞事件循环或未返回标准响应;环境变量和 secrets 需显式声明,conditions 和复杂 !sub 在本地不生效。

本地调试时 sam local invoke 报错找不到函数入口
常见现象是提示 Unable to find a handler path 或 ModuleNotFoundError,本质是 SAM CLI 没法按约定路径加载你的函数代码。Python 函数的入口必须是 handler.py 里的 lambda_handler(或你显式指定的模块+函数名),且该文件得在项目根目录或 CodeUri 指向的路径下。
- 检查
template.yaml中函数的CodeUri是否指向包含handler.py的目录,不是指向单个 .py 文件 -
Handler字段格式必须是module_name.function_name,比如handler.lambda_handler;如果模块在子目录里,得用点号分隔,如src.handler.lambda_handler - 确保
handler.py所在目录有__init__.py(哪怕为空),否则 Python 不认作包,SAM 也无法 import - 运行前先
cd到template.yaml所在目录,SAM CLI 默认从此处解析相对路径
sam local start-api 启动后接口返回 502 或超时
这不是网络问题,而是 Lambda 运行时在本地模拟时卡住了——通常因为函数阻塞了事件循环、没正确返回响应、或依赖了只在真实 AWS 环境才有的服务(比如没 mock 的 boto3 调用)。
- 确认函数体里调用了
return(或yield),不能只 print 或写日志就结束;API Gateway 本地模式要求明确返回 dict 格式的{'statusCode': 200, 'body': '...'} - 禁用真实云服务调用:用
motomockboto3,或把涉及client = boto3.client(...)的逻辑临时注释掉 - 避免使用
time.sleep()或长耗时同步操作;本地模拟没有真正的 Lambda 超时机制,容易假死 - 启动时加
--debug-port 5858并配合 VS Code attach,能快速定位卡在哪一行
环境变量和 Secrets 在本地调试时不生效
SAM CLI 默认不会自动注入 Parameters、Outputs 或 Secrets Manager 引用,所有环境变量都得显式声明在 template.yaml 的函数 Environment.Variables 下,或通过 --env-vars 参数传入 JSON 文件。
- 不要指望
!Ref MyDBEndpoint这类 CloudFormation 内建函数在本地起作用;要么硬编码测试值,要么用--env-vars env.json外部注入 - Secrets Manager 的
!GetAtt MySecret.Arn在本地完全无效;改用os.getenv('SECRET_VALUE', 'test-secret')并在env.json里提供 fallback 值 - 注意大小写:
Environment.Variables里写的DB_HOST,代码里就得用os.environ['DB_HOST'],Python 对大小写敏感
调试时看到 Resource not found 但 template 明明定义了
这是 SAM CLI 解析模板时的“作用域错觉”——它只展开顶层 Resources,不处理嵌套在 Conditions、Mappings 或自定义宏里的资源定义。本地调试阶段,这些逻辑全被跳过。
立即学习“Python免费学习笔记(深入)”;
- 把关键资源(如 DynamoDB 表、S3 Bucket)从
Conditions里移出来,或者干脆删掉条件判断,先让本地跑通 - 避免在
template.yaml里用!Sub拼接资源名再引用,本地解析器对复杂!Sub支持不稳定;直接写死名称更稳妥 - 如果用了 SAM Macros(如
AWS::Serverless-2016-10-31版本以外的扩展),本地调试基本不可用;换回标准 SAM 资源定义
本地调试不是真实 Lambda 环境的镜像,它是带约束的模拟器。最常被忽略的是:函数包结构、环境变量注入时机、以及 CloudFormation 模板中那些“只在部署时才展开”的语法——它们在 sam local 里根本不会执行。










