{"record":{"id":"cf5341869f640477","repo":"apache/answer","slug":"failed-to-open-source-file-s-w","errorCode":null,"errorMessage":"failed to open source file %s: %w","messagePattern":"failed to open source file (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cli/build.go","lineNumber":536,"sourceCode":"\n\t\t// Construct the absolute path for the source file/directory\n\t\tsrcPath := filepath.Join(sourceDir, path)\n\t\tsrcPath = filepath.ToSlash(srcPath)\n\n\t\t// Construct the absolute path for the destination file/directory\n\t\tdstPath := filepath.Join(targetDir, path)\n\n\t\tif d.IsDir() {\n\t\t\t// Create the directory in the destination\n\t\t\terr := os.MkdirAll(dstPath, os.ModePerm)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to create directory %s: %w\", dstPath, err)\n\t\t\t}\n\t\t} else {\n\t\t\t// Open the source file\n\t\t\tsrcFile, err := sourceFs.Open(srcPath)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to open source file %s: %w\", srcPath, err)\n\t\t\t}\n\t\t\tdefer srcFile.Close()\n\n\t\t\t// Create the destination file\n\t\t\tdstFile, err := os.Create(dstPath)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to create destination file %s: %w\", dstPath, err)\n\t\t\t}\n\t\t\tdefer dstFile.Close()\n\n\t\t\t// Copy the file contents\n\t\t\t_, err = io.Copy(dstFile, srcFile)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to copy file contents from %s to %s: %w\", srcPath, dstPath, err)\n\t\t\t}\n\t\t}\n\n\t\treturn nil","sourceCodeStart":518,"sourceCodeEnd":554,"githubUrl":"https://github.com/apache/answer/blob/3b9f1370612e690a0b7f230f05e688930db4c6d3/internal/cli/build.go#L518-L554","documentation":"This error is wrapped and returned by the embedded-FS copy helper in internal/cli/build.go when sourceFs.Open(srcPath) fails while walking the source tree during a build/copy operation. The source filesystem is typically an embed.FS, so files were compiled into the binary, but the joined path (sourceDir + walked path) does not resolve inside that FS — usually a path-joining bug rather than a missing file on disk. The underlying OS/FS error is preserved via %w.","triggerScenarios":"fs.WalkDir over an embed.FS yields a path that, after filepath.Join(sourceDir, path) and filepath.ToSlash, does not exist in the source filesystem; e.g. double slashes, a wrong sourceDir prefix, or opening a path that WalkDir reported but Open cannot resolve (symlinks, case mismatch, Windows backslash leakage).","commonSituations":"Build-time asset copying where sourceDir was configured with a leading/trailing slash mismatch against the embed directive; cross-platform builds where path separators were not normalized; renamed or moved embedded directories after upgrading the codebase.","solutions":["Check the wrapped underlying error in the message to see whether it's ENOENT, ENOTDIR, or invalid path","Verify sourceDir matches the embed.FS root exactly (no leading './' or duplicate slashes) before calling the copy helper","Apply filepath.ToSlash to sourceDir itself before filepath.Join, and re-check the constructed srcPath","If using os.DirFS, confirm the file actually exists on disk and is readable by the build process user"],"exampleFix":"// before\nsrcPath := filepath.Join(sourceDir, path)\n// after\nsrcPath := filepath.ToSlash(filepath.Join(filepath.ToSlash(sourceDir), path))","handlingStrategy":"validation","validationCode":"// before invoking the copy/build operation\nif _, err := fs.Stat(sourceFs, filepath.ToSlash(sourceDir)); err != nil {\n    return fmt.Errorf(\"source dir %q not found in source FS: %w\", sourceDir, err)\n}","typeGuard":null,"tryCatchPattern":"if err := copyDir(sourceFs, sourceDir, targetDir); err != nil {\n    var perr *fs.PathError\n    if errors.As(err, &perr) {\n        log.Printf(\"copy failed on path %s: %v\", perr.Path, perr.Err)\n    }\n    return err\n}","preventionTips":["Normalize sourceDir with filepath.ToSlash and strip leading './' before joining with walked paths","Verify the embed directive covers all files you intend to copy","Test the copy helper on both linux and windows builds to catch separator bugs"],"tags":["go","filesystem","embed-fs","build"],"backgroundTag":"file-open-failed","analyzedSha":"3b9f1370612e690a0b7f230f05e688930db4c6d3","analyzedAt":"2026-09-05T18:18:39.533Z","contentChangedAt":"2026-09-05T18:18:39.533Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}