Repository navigation
ignore_error not working on new built-in cp command #2466
Description
Activity
- addedstate: needs triageWaiting to be triaged by a maintainer.Waiting to be triaged by a maintainer.
on Oct 17, 2025 - addedos: windowsIssues that affect users on Windows.Issues that affect users on Windows.area: execChanges related to the execution of commands.Changes related to the execution of commands.dep: mvdan/shIssues related to the upstream interpreter used by Task.Issues related to the upstream interpreter used by Task.and removedstate: needs triageWaiting to be triaged by a maintainer.Waiting to be triaged by a maintainer.area: execChanges related to the execution of commands.Changes related to the execution of commands.
on Dec 6, 2025 Works on Linux, not on Windows/Powershell. Seems likely that
errors.As()is the cause, but I don't know why. I don't have a devenv for windows ...Line 222 in 2161f33
if errors.As(err, &exitCode) { It is possible that the error returned from mvdan/sh under windows is not the expected type (i.e. not interp.ExitStatus).
https://github.com/mvdan/sh/blob/7ad4e4310897576a02731b31da97dfebe4a2f9cd/interp/handler.go#L161
The error
fs.PathError{Op:"CreateFile"...)fromos.OpenFile(in u-root function copyRegularFile()) is passed directly back to Task. Task has been implemented to expect an error of type interp.ExitStatus, so it does not handle the error from u-root.In mvdan/sh/interp/api.go fromHandlerError() windows code will call fatal(error) which then sets e.code to 1, and e.err to the aforementioned error.
Later on, in mvdan/sh/api.go Run() we see that error is now processed:
// Return the first of: a fatal error, a non-fatal handler error, or the exit code. if err := r.exit.err; err != nil { return err } if code := r.exit.code; code != 0 { return ExitStatus(code) } return niland you see that err has priority over code, so, in the windows case, err is returned ... which triggers the failing condition observed in Task. The "code", although set, is actually lost, which is what eventually breaks the Task code.
With that in mind, there are a few ways to fix this problem; have exitStatus:fatal() wrap the error in an ExitStatus error, or change Task so that it also handles other error conditions.
@andreynering or @pd93 do either of you know of the top of you head how to deal with this kind of problem:
func (e *exitStatus) fatal(err error) { if !e.fatalExit && err != nil { e.exiting = true e.fatalExit = true e.err = err // **** u-root error is directly used here, and Task does not handle that (it looks for interp.ExitStatus) if e.code == 0 { e.code = 1 } } } func (e *exitStatus) fromHandlerError(err error) { if err != nil { var exit errBuiltinExitStatus var es ExitStatus if errors.As(err, &exit) { *e = exitStatus(exit) } else if errors.As(err, &es) { e.err = err // **** task looks for this condition, esp. ExitStatus, which is the case on linux e.code = uint8(es) } else { // **** windows/u-root takes this path e.fatal(err) // handler's custom fatal error } } else { e.code = 0 } }Task seems to be deliberately only enabling the "ignore-error" for interop.ExitStatus errors, which might be sensible (since other errors are probably non-ignorable). So, the problem might need to be solved in the mcdan/sh interp ... specifically in the area identified above, probably by wrapping the err with ExitStatus.
Or, it could be fixed in the coreutils ExecHandler(), by wrapping the error there, before it reaches the above code. I think that could be the better solution.
- addeddep: u-root/u-rootIssues related to the upstream core utils used by Task.Issues related to the upstream core utils used by Task.and removedos: windowsIssues that affect users on Windows.Issues that affect users on Windows.dep: mvdan/shIssues related to the upstream interpreter used by Task.Issues related to the upstream interpreter used by Task.
on Jan 7, 2026 So, the problem might need to be solved in the mcdan/sh interp ... specifically in the area identified above, probably by wrapping the err with ExitStatus.
@trulede Yeah, wrapping the error is probably the right solution here! Just not sure if on the lib (mvdan/sh) or on our handler.
- addeddep: mvdan/shIssues related to the upstream interpreter used by Task.Issues related to the upstream interpreter used by Task.
on Jan 8, 2026 Proposal in the interpreter repo:
- marked Built-in Core Utilities fails catastrophic with no way to catch the error #2699 as a duplicate of this issue
on Feb 20, 2026 It should be fixed by #2943 (and mvdan/sh@1e6494c)
Will be included in the next release
Description
cpcommand to copy a file that may or may not exist, with theignore_error: trueproperty set on thecmd:scopecpcommand errors to be suppressedcperrors were not suppressed and tasks fail-fis used or not.powershellbefore thecpcommand works as expected even if the powershell command fails.This task is just a best-effort file copy for some testing, and some files may not exist for now, and simply suppressing the error is the simplest solution for now.
Example error
Version
3.45.4
Operating system
Windows
Experiments Enabled
None
Example Taskfile