{"record":{"id":"fec6efb01518d0c3","repo":"microsoft/FASTER","slug":"attempting-to-enqueue-into-a-completed-log","errorCode":null,"errorMessage":"Attempting to enqueue into a completed log","messagePattern":"Attempting to enqueue into a completed log","errorType":"exception","errorClass":"FasterException","httpStatus":null,"severity":"error","filePath":"cs/src/core/FasterLog/FasterLog.cs","lineNumber":500,"sourceCode":"        #region TryEnqueue\n        /// <summary>\n        /// Try to enqueue entry to log (in memory). If it returns true, we are\n        /// done. If it returns false, we need to retry.\n        /// </summary>\n        /// <param name=\"entry\">Entry to be enqueued to log</param>\n        /// <param name=\"logicalAddress\">Logical address of added entry</param>\n        /// <typeparam name=\"T\">type of entry</typeparam>\n        /// <returns>Whether the append succeeded</returns>\n        public unsafe bool TryEnqueue<T>(T entry, out long logicalAddress) where T : ILogEnqueueEntry\n        {\n            logicalAddress = 0;\n            var length = entry.SerializedLength;\n            int allocatedLength = headerSize + Align(length);\n            ValidateAllocatedLength(allocatedLength);\n\n            epoch.Resume();\n\n            if (commitNum == long.MaxValue) throw new FasterException(\"Attempting to enqueue into a completed log\");\n\n            logicalAddress = allocator.TryAllocateRetryNow(allocatedLength);\n            if (logicalAddress == 0)\n                if (logicalAddress == 0)\n                {\n                    epoch.Suspend();\n                    if (cannedException != null) throw cannedException;\n                    return false;\n                }\n\n            var physicalAddress = allocator.GetPhysicalAddress(logicalAddress);\n            entry.SerializeTo(new Span<byte>((void*)(headerSize + physicalAddress), length));\n            SetHeader(length, (byte*)physicalAddress);\n            if (AutoRefreshSafeTailAddress) DoAutoRefreshSafeTailAddress();\n            epoch.Suspend();\n            if (AutoCommit) Commit();\n            return true;\n        }","sourceCodeStart":482,"sourceCodeEnd":518,"githubUrl":"https://github.com/microsoft/FASTER/blob/321d872eabda6a0345c8bd76419f89723ed864ae/cs/src/core/FasterLog/FasterLog.cs#L482-L518","documentation":"Enqueue(self, entry, commitNum, ...) rejects entries whose commitNum equals long.MaxValue, the sentinel value the log uses to mark a completed (sealed) log tail. Once the log has been completed via Commit(long.MaxValue)-style APIs, no further enqueues are permitted. The check runs after epoch.Resume() so the exception is thrown directly to the caller.","triggerScenarios":"Calling FasterLog.Enqueue(IBatchEntry/byte[] entry, long commitNum) passing commitNum == long.MaxValue, on a log that has been marked completed.","commonSituations":"Hard-coding or mis-deriving a commit number that collides with the long.MaxValue 'completed' sentinel; a producer that started before Commit(long.MaxValue) and keeps enqueueing afterward; copying example code that used long.MaxValue as an 'unspecified' marker.","solutions":["Pass a normal, monotonically increasing commit number (or the default) instead of long.MaxValue.","Stop producers before calling the commit that completes the log (commit with long.MaxValue is terminal).","Add a guard/check before enqueue: if (commitNum == long.MaxValue) throw/return before touching the log.","Route post-completion writes to a new log instance/device."],"exampleFix":"// before\nlog.Enqueue(data, long.MaxValue); // sentinel means 'completed log'\n// after\nlog.Enqueue(data, ++commitNumber);","handlingStrategy":"validation","validationCode":"if (commitNum == long.MaxValue)\n    throw new InvalidOperationException(\"long.MaxValue marks a completed log; use a real commit number\");","typeGuard":"static bool IsValidCommitNumber(long commitNum) => commitNum != long.MaxValue;","tryCatchPattern":"try { log.Enqueue(data, commitNum); }\ncatch (FasterException ex) when (ex.Message == \"Attempting to enqueue into a completed log\")\n{\n    // log is sealed: redirect writes or stop producer\n}","preventionTips":["Never pass long.MaxValue as a commit number; treat it as a reserved sentinel.","Complete the log only after all producers are shut down.","Centralize commit-number generation in one monotonic source."],"tags":["fasterlog","enqueue","sentinel-value"],"backgroundTag":"invalid-argument-value","analyzedSha":"321d872eabda6a0345c8bd76419f89723ed864ae","analyzedAt":"2026-09-15T22:18:00.693Z","contentChangedAt":"2026-09-15T22:18:00.693Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}