Snakemake v9.0升级后出现DAG评估KeyError,但工作流仍可运行求助
Snakemake v9.0升级后KeyError报错但工作流正常执行的问题分析
问题现象
将气候数据处理管道升级到Snakemake v9.0后,构建DAG时频繁抛出InputFunctionException引发的KeyError,每个目标文件都会触发该错误,但工作流最终仍能正常完成执行。
错误日志
Building DAG of jobs... InputFunctionException in rule primaryVar_ERA5-tas in file "/dmidata/projects/klimaatlas/KAPy/workflow/Snakefile", line 31: Error: KeyError: 'outputs/01.primaryVars/tas/tas_CORDEX_AFR-44_historical+rcp26_ICHEC-EC-EARTH_r12i1p1_MPI-CSC-REMO2009_v1_mon_Ghana-44.nc' Wildcards: fname=tas_CORDEX_AFR-44_historical+rcp26_ICHEC-EC-EARTH_r12i1p1_MPI-CSC-REMO2009_v1_mon_Ghana-44.nc Traceback: File "/dmidata/projects/klimaatlas/KAPy/workflow/Snakefile", line 39, in <lambda> (rule primaryVar_ERA5-tas, line 33, /dmidata/projects/klimaatlas/KAPy/workflow/Snakefile) Use --strict-dag-evaluation to force strict mode.
相关规则代码
#Primary variable singular rule def primaryVar_rule(thisID): thisVarName=config['inputs'][thisID]['varID'] rule: name: f'primaryVar_{thisID}' output: os.path.join(outDirs['primaryVariables'], f"{thisVarName}", "{fname}") input: lambda wildcards: wf['primVars'][thisID][os.path.join(outDirs['primaryVariables'], thisVarName, wildcards.fname)] run: KAPy.buildPrimVar(config=config, inFiles=input, outFile=output, inpID=thisID) for pvID in wf['primVars'].keys(): primaryVar_rule(pvID)
问题分析思路
Snakemake v9.0的DAG评估逻辑变更
Snakemake v9.0对DAG构建阶段的输入函数评估逻辑做了调整,相比旧版本会提前在DAG构建时调用lambda输入函数解析依赖,而旧版本可能仅在作业实际执行阶段才解析。这导致原本隐藏的KeyError在DAG构建阶段被触发,但由于Snakemake默认的宽松模式(错误提示中的--strict-dag-evaluation是严格模式开关),工作流仍会尝试继续执行作业。输入函数的键匹配错误
报错中的KeyError显示,lambda函数尝试用完整输出路径作为键,从wf['primVars'][thisID]字典中查找对应值,但该字典中可能并不存在这个完整路径的键:- 大概率
wf['primVars'][thisID]的键仅为文件名(即wildcards.fname),而非拼接后的完整输出路径; - 也可能存在路径格式不一致的问题,比如字典中存储的是相对路径,而lambda拼接的是绝对路径,或者路径分隔符、末尾斜杠等细节不匹配。
- 大概率
验证与调试方向
- 打印
wf['primVars'][thisID]的所有键,确认键的格式是否与lambda中拼接的路径一致; - 临时修改lambda函数,用
.get()替代直接索引(如wf['primVars'][thisID].get(拼接后的路径, None)),并打印返回值,验证是否能获取到正确的输入文件路径; - 对比旧版本Snakemake的行为,确认是否是版本升级带来的评估时机变化导致报错暴露。
- 打印
潜在修正方案
- 如果
wf['primVars'][thisID]的键是文件名,直接用wildcards.fname作为索引,而非拼接完整路径:lambda wildcards: wf['primVars'][thisID][wildcards.fname] - 若必须用完整路径作为键,确保
wf['primVars'][thisID]中存储的路径与os.path.join(outDirs['primaryVariables'], thisVarName, wildcards.fname)生成的路径完全一致(包括绝对/相对、斜杠等)。
- 如果
内容的提问来源于stack exchange,提问作者Mark Payne
相关产品推荐
相关产品推荐

