{"record":{"id":"d3df56da969d9305","repo":"anomalyco/sst","slug":"no-pyproject-toml-found","errorCode":null,"errorMessage":"no pyproject.toml found","messagePattern":"no pyproject\\.toml found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/runtime/python/project.go","lineNumber":155,"sourceCode":"\n\treturn candidates\n}\n\n// findPyprojectToml searches for pyproject.toml starting from the handler file directory.\nfunc findPyprojectToml(projectRoot, handlerFile string) (string, error) {\n\tcurrentDir := filepath.Dir(handlerFile)\n\tfor {\n\t\tpyprojectPath := filepath.Join(currentDir, \"pyproject.toml\")\n\t\tif _, err := os.Stat(pyprojectPath); err == nil {\n\t\t\treturn pyprojectPath, nil\n\t\t}\n\t\tparentDir := filepath.Dir(currentDir)\n\t\tif parentDir == currentDir || !strings.HasPrefix(currentDir, projectRoot) {\n\t\t\tbreak\n\t\t}\n\t\tcurrentDir = parentDir\n\t}\n\treturn \"\", fmt.Errorf(\"no pyproject.toml found\")\n}\n\n// resolveSourceRoot determines the source root directory.\nfunc resolveSourceRoot(projectRoot, pyprojectPath string) string {\n\tif pyprojectPath != \"\" {\n\t\tpyprojectDir := filepath.Dir(pyprojectPath)\n\t\tsrcDir := filepath.Join(pyprojectDir, \"src\")\n\t\tif _, err := os.Stat(srcDir); err == nil {\n\t\t\treturn srcDir\n\t\t}\n\t\treturn pyprojectDir\n\t}\n\treturn projectRoot\n}\n\n// parsePyprojectToml reads and parses a pyproject.toml file.\nfunc parsePyprojectToml(path string) (*pyprojectConfig, error) {\n\tcontent, err := os.ReadFile(path)","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/pkg/runtime/python/project.go#L137-L173","documentation":"findPyprojectToml walks up from the handler's directory toward projectRoot looking for a pyproject.toml and returns this error when the climb terminates (filesystem root or leaving projectRoot) without finding one. Note: resolveHandler intentionally ignores this error, so it is only fatal when callers invoke findPyprojectToml directly and require a pyproject.toml.","triggerScenarios":"The handler's file and all ancestor directories up to projectRoot (and the walk's break condition on leaving projectRoot) contain no pyproject.toml — i.e. the Python project has no pyproject.toml between the handler file and the project root.","commonSituations":"Plain scripts folder with only requirements.txt and no pyproject.toml; pyproject.toml lives ABOVE the resolved projectRoot (wrong cfgPath root); repo migrated from poetry-less setup; handler resolved into a build/ or venv/ copy that lacks metadata files.","solutions":["Add a minimal pyproject.toml at the project (or source) root declaring your package.","Check that pyproject.toml is between the handler file and projectRoot — if it sits above the root, fix the cfgPath/root dir.","If your project legitimately has none, rely on callers (like resolveHandler) that ignore this error and use requirements-based flows.","Verify the file is named exactly pyproject.toml (no typos like pyproject.toml.txt)."],"exampleFix":"// before: no pyproject.toml in project\n\n// after: create pyproject.toml at project root\n[project]\nname = \"my-app\"\nversion = \"0.1.0\"\nrequires-python = \">=3.11\"","handlingStrategy":"validation","validationCode":"// shell\ncd <project-root> && test -f pyproject.toml && echo OK || echo 'add pyproject.toml between handler file and project root'","typeGuard":null,"tryCatchPattern":"try { await deploy() } catch (e) {\n  if (String(e).includes(\"no pyproject.toml found\"))\n    console.error(\"Create a pyproject.toml at the project/source root\");\n  throw e;\n}","preventionTips":["Always include a pyproject.toml in Python projects deployed with this runtime.","Ensure the cfgPath root does not exclude the directory containing pyproject.toml.","Keep the file at the source root, not in a nested build copy."],"tags":["python","pyproject","project-discovery"],"backgroundTag":"missing-pyproject-toml","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}