{"record":{"id":"7307fa44df201c7e","repo":"anomalyco/sst","slug":"failed-to-find-python-file-for-handler-s-w","errorCode":null,"errorMessage":"failed to find Python file for handler %s: %w","messagePattern":"failed to find Python file for handler (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/runtime/python/project.go","lineNumber":67,"sourceCode":"\t\t\t\t} `toml:\"targets\"`\n\t\t\t} `toml:\"build\"`\n\t\t} `toml:\"hatch\"`\n\n\t\tSetuptools struct {\n\t\t\tPackages struct {\n\t\t\t\tFind struct {\n\t\t\t\t\tWhere []string `toml:\"where\"`\n\t\t\t\t} `toml:\"find\"`\n\t\t\t} `toml:\"packages\"`\n\t\t} `toml:\"setuptools\"`\n\t} `toml:\"tool\"`\n}\n\n// resolveHandler finds and resolves a Python handler.\nfunc resolveHandler(projectRoot, handlerPath string) (*projectInfo, error) {\n\thandlerFile, err := findPythonFile(projectRoot, handlerPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to find Python file for handler %s: %w\", handlerPath, err)\n\t}\n\n\tpyprojectPath, _ := findPyprojectToml(projectRoot, handlerFile)\n\n\tinfo := &projectInfo{\n\t\tProjectRoot:   projectRoot,\n\t\tPyprojectPath: pyprojectPath,\n\t}\n\n\tinfo.SourceRoot = resolveSourceRoot(projectRoot, pyprojectPath)\n\n\treturn info, nil\n}\n\n// findPythonFile locates the Python file for the given handler path.\nfunc findPythonFile(projectRoot, handlerPath string) (string, error) {\n\tfilePath := extractFilePath(handlerPath)\n\tcandidates := generateCandidatePaths(projectRoot, filePath)","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/pkg/runtime/python/project.go#L49-L85","documentation":"resolveHandler wraps any failure from findPythonFile (the underlying candidate-path search) into \"failed to find Python file for handler %s\". It is thrown while resolving the function's handler entry (e.g. \"src/api.handler\") to an actual .py file on disk during build. The %w chain preserves the underlying reason (abs-path failure or 'handler not found').","triggerScenarios":"Called from PythonRuntime.Build (and tests) with input.Handler set to a path whose derived file does not exist anywhere in the candidate directories (project root, src/, app/, functions/, lambda/, handlers/, lib/) relative to the resolved root dir of cfgPath.","commonSituations":"Typo in the handler field of the function config; handler written as a module symbol path that doesn't map to a file (e.g. wrong casing on case-sensitive filesystems); the sst.config.ts cfgPath root differs from where the Python code lives in a monorepo; the file was renamed but config not updated.","solutions":["Verify the handler value in your function config matches a real file path relative to the project root, e.g. \"src/api/index.handler\" for src/api/index.py.","Check file-name casing and the .py extension; the resolver is case-sensitive and only accepts .py files.","Confirm you are deploying from the directory you intend (root dir is resolved from cfgPath); move the code or fix the config path.","Print/log the candidate search by checking the wrapped 'handler not found: ... (searched N candidate paths)' detail for hints."],"exampleFix":"// before (sst.config.ts)\nhandler: \"src/apoi.handler\"\n\n// after\nhandler: \"src/api.handler\"","handlingStrategy":"validation","validationCode":"// node/bun, before deploy\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nconst handler = \"src/api.handler\";\nconst file = handler.replace(/\\.handler$/, \".py\").split(\".\").slice(0, -1).join(\".\");\nconst dirs = [\"\", \"src\", \"app\", \"functions\", \"lambda\", \"handlers\", \"lib\"];\nif (!dirs.some(d => existsSync(path.join(root, d, file + \".py\"))))\n  throw new Error(`handler target missing: ${file}.py`);","typeGuard":null,"tryCatchPattern":"try { await deploy() } catch (e) {\n  if (String(e).includes(\"failed to find Python file for handler\"))\n    console.error(\"Fix handler path in config:\", String(e));\n  throw e;\n}","preventionTips":["Keep handler values as paths relative to the sst project root ending in .handler.","Verify with ls before deploying after any rename.","Use consistent file naming (avoid case-only differences)."],"tags":["python","handler-resolution","file-not-found","config"],"backgroundTag":"handler-file-not-found","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}