anomalyco/sst · error
failed to find Python file for handler %s: %w
Error message
failed to find Python file for handler %s: %w
What it means
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').
Source
Thrown at pkg/runtime/python/project.go:67
} `toml:"targets"`
} `toml:"build"`
} `toml:"hatch"`
Setuptools struct {
Packages struct {
Find struct {
Where []string `toml:"where"`
} `toml:"find"`
} `toml:"packages"`
} `toml:"setuptools"`
} `toml:"tool"`
}
// resolveHandler finds and resolves a Python handler.
func resolveHandler(projectRoot, handlerPath string) (*projectInfo, error) {
handlerFile, err := findPythonFile(projectRoot, handlerPath)
if err != nil {
return nil, fmt.Errorf("failed to find Python file for handler %s: %w", handlerPath, err)
}
pyprojectPath, _ := findPyprojectToml(projectRoot, handlerFile)
info := &projectInfo{
ProjectRoot: projectRoot,
PyprojectPath: pyprojectPath,
}
info.SourceRoot = resolveSourceRoot(projectRoot, pyprojectPath)
return info, nil
}
// findPythonFile locates the Python file for the given handler path.
func findPythonFile(projectRoot, handlerPath string) (string, error) {
filePath := extractFilePath(handlerPath)
candidates := generateCandidatePaths(projectRoot, filePath)View on GitHub (pinned to a0bd20f762)
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.
Example fix
// before (sst.config.ts) handler: "src/apoi.handler" // after handler: "src/api.handler"
Defensive patterns
Strategy: validation
Validate before calling
// node/bun, before deploy
import { existsSync } from "node:fs";
import path from "node:path";
const handler = "src/api.handler";
const file = handler.replace(/\.handler$/, ".py").split(".").slice(0, -1).join(".");
const dirs = ["", "src", "app", "functions", "lambda", "handlers", "lib"];
if (!dirs.some(d => existsSync(path.join(root, d, file + ".py"))))
throw new Error(`handler target missing: ${file}.py`); Try / catch
try { await deploy() } catch (e) {
if (String(e).includes("failed to find Python file for handler"))
console.error("Fix handler path in config:", String(e));
throw e;
} Prevention
- 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).
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- handler not found: %s (searched %d candidate paths)
- Handler not found: %v
- failed to read requirements file: %w
- You cannot provide both "job" and "function" in the "${name}
- You cannot provide both a function and a task in the "${name
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/7307fa44df201c7e.
Report an issue: GitHub.