{"record":{"id":"c3465a0384a91baf","repo":"pulumi/pulumi","slug":"opening-s-w-c3465a","errorCode":null,"errorMessage":"opening %s: %w","messagePattern":"opening (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdk/python/toolchain/uv.go","lineNumber":198,"sourceCode":"\t\t}\n\t\t// pyproject.toml exists but has no [project]. If requirements.txt sits next to it, append a minimal\n\t\t// [project] section and merge the deps in.\n\t\trequirementsTxt := filepath.Join(existingPyprojectDir, \"requirements.txt\")\n\t\tif _, statErr := os.Stat(requirementsTxt); statErr != nil {\n\t\t\tif errors.Is(statErr, os.ErrNotExist) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"error while looking for requirements.txt: %w\", statErr)\n\t\t}\n\t\tname := projectName\n\t\tif name == \"\" {\n\t\t\tname = filepath.Base(existingPyprojectDir)\n\t\t}\n\t\tpyprojectPath := filepath.Join(existingPyprojectDir, \"pyproject.toml\")\n\t\tsection := fmt.Sprintf(\"\\n[project]\\nname = %q\\nversion = \\\"0.1.0\\\"\\ndependencies = []\\n\", name)\n\t\tf, err := os.OpenFile(pyprojectPath, os.O_APPEND|os.O_WRONLY, 0)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"opening %s: %w\", pyprojectPath, err)\n\t\t}\n\t\tif _, err := f.WriteString(section); err != nil {\n\t\t\tcontract.IgnoreClose(f)\n\t\t\treturn fmt.Errorf(\"appending [project] to %s: %w\", pyprojectPath, err)\n\t\t}\n\t\tif err := f.Close(); err != nil {\n\t\t\treturn fmt.Errorf(\"closing %s: %w\", pyprojectPath, err)\n\t\t}\n\t\treturn u.mergeRequirementsTxt(ctx, existingPyprojectDir, showOutput, infoWriter, errorWriter)\n\t}\n\n\trequirementsTxtDir, err := searchup(cwd, \"requirements.txt\")\n\tpyprojectTomlDir := cwd\n\thasRequirementsTxt := false\n\tif err == nil {\n\t\tpyprojectTomlDir = requirementsTxtDir\n\t\thasRequirementsTxt = true\n\t} else if !errors.Is(err, os.ErrNotExist) {","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/sdk/python/toolchain/uv.go#L180-L216","documentation":"When appending a minimal [project] section to an existing pyproject.toml, os.OpenFile with O_APPEND|O_WRONLY failed. This typically means the file cannot be opened for writing, e.g. it does not actually exist, is read-only, or permissions block writes.","triggerScenarios":"PrepareProject found a pyproject.toml without a [project] section and a requirements.txt next to it, then failed to open that pyproject.toml for appending (EACCES on read-only file, file deleted between searchup and open, EISDIR).","commonSituations":"pyproject.toml checked into git as read-only or with 444 permissions; running pulumi as a different user than the file owner; read-only container filesystem; build system resetting file mode.","solutions":["Make pyproject.toml writable: chmod u+w <path>/pyproject.toml","Run pulumi as the user who owns the project directory","Manually add a [project] section (name, version, dependencies) to pyproject.toml so the append path is skipped","Ensure the file exists and is a regular file, not a directory or dangling symlink"],"exampleFix":"// before\n-r--r--r-- pyproject.toml\n// after\n$ chmod u+w pyproject.toml","handlingStrategy":"validation","validationCode":"import os\npath = \"pyproject.toml\"\nassert os.path.isfile(path), f\"{path} missing or not a file\"\nassert os.access(path, os.W_OK), f\"{path} not writable: run chmod u+w {path}\"","typeGuard":null,"tryCatchPattern":"try {\n    await runPulumi();\n} catch (e) {\n    if (String(e).includes(\"opening \") && String(e).includes(\"pyproject.toml\")) {\n        console.error(\"pyproject.toml not writable; fix file mode or run as file owner\");\n    }\n    throw e;\n}","preventionTips":["Do not commit pyproject.toml with read-only modes (444)","Run pulumi as the same user that owns the project files","Add a [project] section manually so the append step never runs","Avoid read-only container filesystems for project directories"],"tags":["filesystem","python","uv","file-writable"],"backgroundTag":"file-open-permission-denied","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}