{"record":{"id":"b516c2d8cfc89c3b","repo":"golang/go","slug":"s-d-w","errorCode":null,"errorMessage":"%s:%d: %w","messagePattern":"%s:%d: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/internal/script/engine.go","lineNumber":193,"sourceCode":"\t\t\t_, err = fmt.Fprintf(log, \" (%.3fs)\\n\", time.Since(sectionStart).Seconds())\n\n\t\t\tif err == nil && (!ok || !e.Quiet) {\n\t\t\t\terr = s.flushLog(log)\n\t\t\t} else {\n\t\t\t\ts.log.Reset()\n\t\t\t}\n\t\t}\n\n\t\tsectionStart = time.Time{}\n\t\treturn err\n\t}\n\n\tvar lineno int\n\tlineErr := func(err error) error {\n\t\tif _, ok := errors.AsType[*CommandError](err); ok {\n\t\t\treturn err\n\t\t}\n\t\treturn fmt.Errorf(\"%s:%d: %w\", file, lineno, err)\n\t}\n\n\t// In case of failure or panic, flush any pending logs for the section.\n\tdefer func() {\n\t\tif sErr := endSection(false); sErr != nil && err == nil {\n\t\t\terr = lineErr(sErr)\n\t\t}\n\t}()\n\n\tfor {\n\t\tif err := s.ctx.Err(); err != nil {\n\t\t\t// This error wasn't produced by any particular command,\n\t\t\t// so don't wrap it in a CommandError.\n\t\t\treturn lineErr(err)\n\t\t}\n\n\t\tline, err := script.ReadString('\\n')\n\t\tif err == io.EOF {","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/internal/script/engine.go#L175-L211","documentation":"The lineErr closure in Engine.Run wraps any error that is not already a *CommandError with the script's filename and line number, giving every script failure a precise location. It fires for errors not tied to a single command's CommandError — script-reader I/O failures, context cancellation, end-of-section log-flush failures, or a custom Cmd that returns a bare error.","triggerScenarios":"s.ctx.Err() is non-nil (test cancelled/timed out) at engine.go:204; script.ReadString returns an I/O error; endSection fails while flushing logs; or a custom Cmd implementation returns errors.New(...) directly instead of wrapping via cmdError, so lineErr adds the file:line prefix.","commonSituations":"Test timeout cancelling the script context; a custom command returning a plain error; a log writer (io.Writer) failing; reaching this when debugging which script line caused a panic.","solutions":["Read the wrapped error (the %w portion) for the actual root cause and address that.","If the cause is context cancellation, find the hang or increase the test timeout via testing.T.Deadline/-timeout.","If authoring a custom Cmd, wrap failures with cmdError(cmd, err) so they are not double-wrapped and keep their CommandError identity.","If the log writer failed, check the io.Writer passed to Run for faults (closed pipe, full buffer)."],"exampleFix":"// before (custom Cmd returns a bare error)\nfunc(s *script.State, args ...string) (script.WaitFunc, error) {\n    return nil, errors.New(\"setup failed\")\n}\n// after\nfunc(s *script.State, args ...string) (script.WaitFunc, error) {\n    return nil, cmdError(cmd, errors.New(\"setup failed\"))\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// When authoring a custom Cmd, wrap errors so they keep CommandError identity\n// and are not re-wrapped by lineErr with just a file:line prefix.\n\nrunErr := impl.Run(s, cmd.args...)\nif runErr != nil {\n    return cmdError(cmd, runErr) // preserves CommandError, lineErr leaves it alone\n}\nreturn nil","preventionTips":["Always wrap custom-command errors with cmdError(cmd, err).","Set realistic test -timeout values to avoid context-cancellation wrappers masking a hang.","When a file:line error appears, read the inner %w error first — it is the root cause."],"tags":["go-script-test","error-wrapping","go-toolchain"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}