{"record":{"id":"fb8089232e45f0a7","repo":"router-for-me/CLIProxyAPI","slug":"observation-barrier-revision-must-not-be-negative","errorCode":null,"errorMessage":"observation barrier revision must not be negative","messagePattern":"observation barrier revision must not be negative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/config/credential_concurrency.go","lineNumber":147,"sourceCode":"\tif !c.busyRetryMinPresent && c.BusyRetryMin == 0 {\n\t\tc.BusyRetryMin = defaultBusyRetryMin\n\t}\n\tif !c.busyRetryMaxPresent && c.BusyRetryMax == 0 {\n\t\tc.BusyRetryMax = defaultBusyRetryMax\n\t}\n\tif !c.maxLimitPresent && c.MaxLimit == 0 {\n\t\tc.MaxLimit = maxCredentialConcurrencyLimit\n\t}\n\treturn c\n}\n\n// ValidateCredentialConcurrency validates values intrinsic to a credential concurrency configuration.\nfunc ValidateCredentialConcurrency(cfg CredentialConcurrencyConfig) error {\n\tif cfg.LifecycleConfigRevision < 0 || (cfg.lifecycleConfigRevisionPresent && cfg.LifecycleConfigRevision == 0) {\n\t\treturn fmt.Errorf(\"lifecycle configuration revision must be positive when present\")\n\t}\n\tif cfg.ObservationBarrierRevision < 0 {\n\t\treturn fmt.Errorf(\"observation barrier revision must not be negative\")\n\t}\n\tif cfg.CPAHeartbeatTimeout <= 0 || cfg.CPACancelBound <= 0 || cfg.ReclaimGrace <= 0 || cfg.CleanupInterval <= 0 {\n\t\treturn fmt.Errorf(\"credential concurrency lifecycle durations must be positive\")\n\t}\n\tif cfg.ReleaseFlushInterval <= 0 || cfg.ReleaseMaxBackoff <= 0 || cfg.BusyRetryMin <= 0 || cfg.BusyRetryMax <= 0 {\n\t\treturn fmt.Errorf(\"credential concurrency limiter durations must be positive\")\n\t}\n\tif cfg.ReleaseMaxBackoff < cfg.ReleaseFlushInterval {\n\t\treturn fmt.Errorf(\"credential concurrency release max backoff must not be less than release flush interval\")\n\t}\n\tif cfg.BusyRetryMin%time.Millisecond != 0 || cfg.BusyRetryMax%time.Millisecond != 0 {\n\t\treturn fmt.Errorf(\"credential concurrency busy retry durations must be whole milliseconds\")\n\t}\n\tif cfg.BusyRetryMax < cfg.BusyRetryMin {\n\t\treturn fmt.Errorf(\"credential concurrency busy retry max must not be less than busy retry min\")\n\t}\n\tif cfg.MaxLimit < 1 || cfg.MaxLimit > maxCredentialConcurrencyLimit {\n\t\treturn fmt.Errorf(\"credential concurrency max limit must be between 1 and %d\", maxCredentialConcurrencyLimit)","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/config/credential_concurrency.go#L129-L165","documentation":"ValidateCredentialConcurrency rejects a negative value for 'credential-concurrency.observation-barrier-revision'. This revision orders the observation barrier handshake for in-flight credential accounting; unlike the lifecycle revision, zero is allowed (unset/default), but any negative value is invalid.","triggerScenarios":"config.yaml with 'credential-concurrency:\\n  observation-barrier-revision: -1' or any negative integer under that key.","commonSituations":"Template systems substituting -1 as a 'not set' sentinel for integers; hand-editing revisions and accidentally flipping the sign; copying fixture data from tests that exercise invalid inputs.","solutions":["Set observation-barrier-revision to 0 or a positive integer.","If your templating uses -1 as 'unset', remove the key from the template instead of emitting -1.","Re-run config validation via server startup or the management API to confirm."],"exampleFix":"# before (config.yaml)\ncredential-concurrency:\n  observation-barrier-revision: -1\n\n# after\ncredential-concurrency:\n  observation-barrier-revision: 1","handlingStrategy":"validation","validationCode":"// Go: guard observation-barrier-revision before submission.\nif cfg.CredentialConcurrency.ObservationBarrierRevision < 0 {\n    return errors.New(\"observation-barrier-revision must be >= 0\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use 0 (or omit) for 'not set'; never negative sentinels like -1.","Adjust templates so unset integers remove the key instead of emitting -1."],"tags":["config","validation","credential-concurrency","revision"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}