{"record":{"id":"7731594088b8058c","repo":"microsoft/FASTER","slug":"fast-forwarding-a-commit-is-only-allowed-when-no-cookie","errorCode":null,"errorMessage":"Fast forwarding a commit is only allowed when no cookie, commit num, or callback is specified","messagePattern":"Fast forwarding a commit is only allowed when no cookie, commit num, or callback is specified","errorType":"exception","errorClass":"FasterException","httpStatus":null,"severity":"error","filePath":"cs/src/core/FasterLog/FasterLog.cs","lineNumber":2707,"sourceCode":"            }\n\n            record.Return();\n            return length;\n        }\n\n\n        private bool CommitInternal(out long commitTail, out long actualCommitNum, bool fastForwardAllowed, byte[] cookie, long proposedCommitNum, Action callback)\n        {\n            if (cannedException != null)\n                throw cannedException;\n\n            commitTail = actualCommitNum = 0;\n\n            if (readOnlyMode)\n                throw new FasterException(\"Cannot commit in read-only mode\");\n\n            if (fastForwardAllowed && (cookie != null || proposedCommitNum != -1 || callback != null))\n                throw new FasterException(\n                    \"Fast forwarding a commit is only allowed when no cookie, commit num, or callback is specified\");\n\n            var info = new FasterLogRecoveryInfo\n            {\n                FastForwardAllowed = fastForwardAllowed,\n                Cookie = cookie,\n                Callback = callback,\n            };\n            info.SnapshotIterators(PersistedIterators);\n            var commitRequired = ShouldCommmitMetadata(ref info) || (commitCoveredAddress < TailAddress);\n            // Only apply commit policy if not a strong commit\n            if (fastForwardAllowed && !commitPolicy.AdmitCommit(TailAddress, commitRequired))\n                return false;\n\n            // This critical section serializes commit record creation / commit content generation and ensures that the\n            // long address are sorted in outstandingCommitRecords. Ok because we do not expect heavy contention on the\n            // commit code path\n            lock (ongoingCommitRequests)","sourceCodeStart":2689,"sourceCodeEnd":2725,"githubUrl":"https://github.com/microsoft/FASTER/blob/321d872eabda6a0345c8bd76419f89723ed864ae/cs/src/core/FasterLog/FasterLog.cs#L2689-L2725","documentation":"The fast-forward commit overload of FasterLog was called while also supplying a cookie, a proposed commit number, or a callback. Fast-forwarding resets commit metadata and is only defined when no extra commit payload or hook is attached; the guard at FasterLog.cs:2707 rejects any combination.","triggerScenarios":"Calling CommitAsync(fastForwardAllowed: true, cookie: ..., callback: ...) or passing a proposedCommitNum != -1 together with fastForwardAllowed = true.","commonSituations":"Developers reusing one generic CommitAsync wrapper with optional parameters, so cookie/callback arguments that were null in normal commits end up non-null when the fast-forward flag is enabled during recovery or replication catch-up.","solutions":["Call the fast-forward commit with only the fastForwardAllowed flag: pass null cookie, -1 commit num, null callback.","If you need a cookie or callback, do a normal (non-fast-forward) CommitAsync instead.","Split the code path: use fast-forward only for recovery/replica catch-up, normal commit for appends.","Audit wrapper methods that forward all optional parameters and default them to null/-1 when fast-forwarding."],"exampleFix":"// before\nawait log.CommitAsync(fastForward: true, cookie: myCookie, commitNum: seq, callback: OnCommit);\n\n// after\nawait log.CommitAsync(fastForward: true, cookie: null, commitNum: -1, callback: null);","handlingStrategy":"validation","validationCode":"if (fastForward && (cookie != null || commitNum != -1 || callback != null)) throw new ArgumentException(\"Fast-forward commit accepts no cookie, commit num, or callback\");","typeGuard":null,"tryCatchPattern":"try { await log.CommitAsync(true, null, -1, null); } catch (FasterException ex) when (ex.Message.Contains(\"Fast forwarding a commit\")) { /* fall back to normal commit */ }","preventionTips":["Use dedicated overloads/wrappers per commit mode","Default optional commit parameters to null/-1","Document that fast-forward is recovery-only"],"tags":["fasterlog","commit","fast-forward","invalid-arguments"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"321d872eabda6a0345c8bd76419f89723ed864ae","analyzedAt":"2026-09-15T22:18:00.693Z","contentChangedAt":"2026-09-15T22:18:00.693Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}