{"record":{"id":"e172244cf0c90f46","repo":"github/copilot-sdk","slug":"ignoring-a-background-factory-progress-flush-failu","errorCode":null,"errorMessage":"Ignoring a background factory progress flush failure after the factory body settled","messagePattern":"Ignoring a background factory progress flush failure after the factory body settled","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"nodejs/src/session.ts","lineNumber":287,"sourceCode":"                        this.flushFailed = true;\n                        this.flushError = error;\n                    }\n                }\n            });\n        }\n        await this.flushTail;\n        if (this.flushFailed) {\n            throw this.flushError;\n        }\n    }\n\n    async close(): Promise<void> {\n        this.closed = true;\n        this.clearFlushTimer();\n        const lines = this.pending.splice(0);\n        await this.flushTail;\n        if (this.flushFailed) {\n            console.warn(\n                \"Ignoring a background factory progress flush failure after the factory body settled\",\n                this.flushError\n            );\n        }\n        if (lines.length > 0) {\n            try {\n                await this.send(lines);\n            } catch (error) {\n                console.warn(\n                    \"Failed to flush final factory progress after the factory body settled\",\n                    error\n                );\n            }\n        }\n    }\n\n    private scheduleFlush(): void {\n        if (this.flushTimer !== undefined) {","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/nodejs/src/session.ts#L269-L305","documentation":"Not a thrown exception but a console warning emitted from close() (nodejs/src/session.ts:287): when the background factory-progress flush task (flushTail) previously failed (flushFailed set) while the session was streaming, close() awaits it and then logs this warning with the stored flushError. It tells the developer some progress events may not have been flushed, but close() continues deliberately and does not fail.","triggerScenarios":"Calling session.close() after a background flush of pending factory progress lines already rejected asynchronously (stream errored, pipe broken, or disk full mid-flight), so this.flushFailed is true and this.flushError is set when close() awaits this.flushTail.","commonSituations":"Output stream (file/pipe/socket) was closed or broke while the session was still running; process exit raced a pending flush; disk-full or EPIPE caused a flush rejection and the timer-driven retry also failed.","solutions":["Check the accompanying flushError in the warning for the underlying stream failure","Verify the destination stream/pipe stayed writable for the session's lifetime (file handle not closed early, pipe consumer alive)","Drain/await pending progress lines before closing, or re-persist the lines pending at close()","Treat the warning as a data-loss signal: re-send or log the unflushed progress events"],"exampleFix":"// before\nawait session.close(); // flush failure only surfaces as a console warning\n// after\nif (session.flushFailed) await persistProgress(session.pendingLines);\nawait session.close();","handlingStrategy":"try-catch","validationCode":"// before close, ensure the stream is still writable\nif (session.outputStream.destroyed || session.outputStream.writableEnded) {\n  console.warn('Progress output stream already closed; progress may be lost');\n}","typeGuard":"function hasFlushError(s) {\n  return s.flushFailed === true && s.flushError instanceof Error;\n}","tryCatchPattern":"try {\n  await session.close();\n} catch (err) {\n  console.error('close failed', err); // the flush warning itself is non-fatal\n} finally {\n  if (session.flushFailed) persistProgress(session.pendingLines); // recover unflushed data\n}","preventionTips":["Keep the destination stream open until after close() resolves","Track flush errors (flushFailed/flushError) at runtime instead of relying on the console warning at close","Periodically flush pending lines with a shorter timer so bursts do not accumulate","Back up unflushed progress lines before closing if delivery guarantees matter"],"tags":["flush","background-task","stream","data-loss"],"backgroundTag":"broken-pipe","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}